Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79789bb558 | |||
| 2e919df2b4 | |||
| 75cd1335cc | |||
| cd103ccf73 | |||
| d0ff9738eb | |||
| 00c1cd7db7 | |||
| 1e091b8871 | |||
| 1295b98fcc | |||
| 7375c11ecd | |||
| e5aa60b742 | |||
| d9133465eb | |||
| 3f5c61c327 | |||
| ace12f8cd7 | |||
| 9d509e07f5 | |||
| 305e52010c | |||
| 6dd13c00ba | |||
| 8703e0ee13 | |||
| 9bac3faae9 | |||
| 7ef93343a4 | |||
| f07eb17a33 | |||
| b97579dfec | |||
| 2ec72f948d | |||
| b45e8b2a29 | |||
| 29e6441d32 | |||
| 445ee723c2 | |||
| 01e235c058 | |||
| fad2dc9a15 |
@@ -10,7 +10,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "7.2.3",
|
||||
"version": "7.3.0",
|
||||
"source": "./plugin",
|
||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||
}
|
||||
|
||||
+37
-16
@@ -4,16 +4,6 @@ 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/).
|
||||
|
||||
## [7.2.2] - 2025-12-15
|
||||
|
||||
## Changes
|
||||
|
||||
- **Refactor:** Consolidate mem-search skill, remove desktop-skill duplication
|
||||
- Delete separate `desktop-skill/` directory (was outdated)
|
||||
- Generate `mem-search.zip` during build from `plugin/skills/mem-search/`
|
||||
- Update docs with correct MCP tool list and new download path
|
||||
- Single source of truth for Claude Desktop skill
|
||||
|
||||
## [7.3.0] - 2025-12-15
|
||||
|
||||
## Features
|
||||
@@ -33,6 +23,37 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Fixed skillPath variable scoping bug in instructions endpoint
|
||||
- Extracted magic numbers to named constants for better code maintainability
|
||||
|
||||
## [7.2.4] - 2025-12-15
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Documentation
|
||||
- Updated endless mode setup instructions with improved configuration guidance for better user experience
|
||||
|
||||
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v7.2.3...v7.2.4
|
||||
|
||||
## [7.2.3] - 2025-12-15
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Fix MCP server failures on plugin updates**: Add 2-second pre-restart delay in `ensureWorkerVersionMatches()` to give files time to sync before killing the old worker. This prevents the race condition where the worker restart happened too quickly after plugin file updates, causing "Worker service connection failed" errors.
|
||||
|
||||
## Changes
|
||||
|
||||
- Add `PRE_RESTART_SETTLE_DELAY` constant (2000ms) to `hook-constants.ts`
|
||||
- Add delay before `ProcessManager.restart()` call in `worker-utils.ts`
|
||||
- Fix pre-existing bug where `port` variable was undefined in error logging
|
||||
|
||||
## [7.2.2] - 2025-12-15
|
||||
|
||||
## Changes
|
||||
|
||||
- **Refactor:** Consolidate mem-search skill, remove desktop-skill duplication
|
||||
- Delete separate `desktop-skill/` directory (was outdated)
|
||||
- Generate `mem-search.zip` during build from `plugin/skills/mem-search/`
|
||||
- Update docs with correct MCP tool list and new download path
|
||||
- Single source of truth for Claude Desktop skill
|
||||
|
||||
## [7.2.1] - 2025-12-14
|
||||
|
||||
## Translation Script Enhancements
|
||||
@@ -2421,12 +2442,12 @@ None (patch version)
|
||||
|
||||
## [4.3.0] - 2025-10-25
|
||||
|
||||
## What's Changed
|
||||
* feat: Enhanced context hook with session observations and cross-platform improvements by @thedotmack in https://github.com/thedotmack/claude-mem/pull/25
|
||||
|
||||
## New Contributors
|
||||
* @thedotmack made their first contribution in https://github.com/thedotmack/claude-mem/pull/25
|
||||
|
||||
## What's Changed
|
||||
* feat: Enhanced context hook with session observations and cross-platform improvements by @thedotmack in https://github.com/thedotmack/claude-mem/pull/25
|
||||
|
||||
## New Contributors
|
||||
* @thedotmack made their first contribution in https://github.com/thedotmack/claude-mem/pull/25
|
||||
|
||||
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v4.2.11...v4.3.0
|
||||
|
||||
## [4.2.10] - 2025-10-25
|
||||
|
||||
@@ -79,7 +79,7 @@ Restart Claude Code. Context from previous sessions will automatically appear in
|
||||
|
||||
- 🧠 **Persistent Memory** - Context survives across sessions
|
||||
- 📊 **Progressive Disclosure** - Layered memory retrieval with token cost visibility
|
||||
- 🔍 **Skill-Based Search** - Query your project history with mem-search skill (~2,250 token savings)
|
||||
- 🔍 **Skill-Based Search** - Query your project history with mem-search skill
|
||||
- 🖥️ **Web Viewer UI** - Real-time memory stream at http://localhost:37777
|
||||
- 💻 **Claude Desktop Skill** - Search memory from Claude Desktop conversations
|
||||
- 🔒 **Privacy Control** - Use `<private>` tags to exclude sensitive content from storage
|
||||
@@ -161,7 +161,7 @@ npx mintlify dev
|
||||
2. **Smart Install** - Cached dependency checker (pre-hook script, not a lifecycle hook)
|
||||
3. **Worker Service** - HTTP API on port 37777 with web viewer UI and 10 search endpoints, managed by Bun
|
||||
4. **SQLite Database** - Stores sessions, observations, summaries with FTS5 full-text search
|
||||
5. **mem-search Skill** - Natural language queries with progressive disclosure (~2,250 token savings vs MCP)
|
||||
5. **mem-search Skill** - Natural language queries with progressive disclosure
|
||||
6. **Chroma Vector Database** - Hybrid semantic + keyword search for intelligent context retrieval
|
||||
|
||||
See [Architecture Overview](https://docs.claude-mem.ai/architecture/overview) for details.
|
||||
@@ -175,7 +175,6 @@ Claude-Mem provides intelligent search through the mem-search skill that auto-in
|
||||
**How It Works:**
|
||||
- Just ask naturally: *"What did we do last session?"* or *"Did we fix this bug before?"*
|
||||
- Claude automatically invokes the mem-search skill to find relevant context
|
||||
- ~2,250 token savings per session start vs MCP approach
|
||||
|
||||
**Available Search Operations:**
|
||||
|
||||
@@ -206,6 +205,8 @@ See [Search Tools Guide](https://docs.claude-mem.ai/usage/search-tools) for deta
|
||||
|
||||
## Beta Features & Endless Mode
|
||||
|
||||
> **Note**: Endless Mode is an **experimental feature in the beta branch only**. It is not included in the stable release you install via the marketplace. You must manually switch to the beta channel to try it, and it comes with significant caveats (see below).
|
||||
|
||||
Claude-Mem offers a **beta channel** with experimental features. Switch between stable and beta versions directly from the web viewer UI.
|
||||
|
||||
### How to Try Beta
|
||||
@@ -230,13 +231,17 @@ Working Memory (Context): Compressed observations (~500 tokens each)
|
||||
Archive Memory (Disk): Full tool outputs preserved for recall
|
||||
```
|
||||
|
||||
**Expected Results**:
|
||||
- ~95% token reduction in context window
|
||||
- ~20x more tool uses before context exhaustion
|
||||
**Projected Results** (based on theoretical modeling, not production measurements):
|
||||
- Significant token reduction in context window
|
||||
- More tool uses before context exhaustion
|
||||
- Linear O(N) scaling instead of quadratic O(N²)
|
||||
- Full transcripts preserved for perfect recall
|
||||
|
||||
**Caveats**: Adds latency (60-90s per tool for observation generation), still experimental.
|
||||
**Important Caveats**:
|
||||
- **Not in stable release** - You must switch to beta branch to use this feature
|
||||
- **Still in development** - May have bugs, breaking changes, or incomplete functionality
|
||||
- **Slower than standard mode** - Blocking observation generation adds latency to each tool use
|
||||
- **Theoretical projections** - The efficiency claims above are based on simulations, not real-world production data
|
||||
|
||||
See [Beta Features Documentation](https://docs.claude-mem.ai/beta-features) for details.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ description: "mem-search skill with HTTP API and progressive disclosure"
|
||||
|
||||
# Search Architecture
|
||||
|
||||
Claude-Mem uses a skill-based search architecture that provides intelligent memory retrieval through natural language queries. This replaced the MCP-based approach in v5.4.0, saving ~2,250 tokens per session start. The skill was enhanced and renamed to "mem-search" in v5.5.0 for better scope differentiation.
|
||||
Claude-Mem uses a skill-based search architecture that provides intelligent memory retrieval through natural language queries. This replaced the MCP-based approach in v5.4.0 with a more efficient implementation. The skill was enhanced and renamed to "mem-search" in v5.5.0 for better scope differentiation.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -133,7 +133,7 @@ Invoke this skill when users ask about:
|
||||
...
|
||||
```
|
||||
|
||||
**Token Savings**: ~2,250 tokens per session start (90% reduction)
|
||||
**Token Efficiency**: Minimal frontmatter at session start with progressive disclosure
|
||||
|
||||
## HTTP API Endpoints
|
||||
|
||||
@@ -341,14 +341,14 @@ All user-provided search queries are properly escaped to prevent SQL injection.
|
||||
### 1. Token Efficiency
|
||||
|
||||
**Before (MCP)**:
|
||||
- Session start: ~2,500 tokens for tool definitions
|
||||
- Session start: All tool definitions loaded upfront
|
||||
- Every session pays this cost
|
||||
- No progressive disclosure
|
||||
|
||||
**After (Skill)**:
|
||||
- Session start: ~250 tokens for skill frontmatter
|
||||
- Full instructions: ~2,500 tokens (only when invoked)
|
||||
- Net savings: ~2,250 tokens per session (~90% reduction)
|
||||
- Session start: Minimal token cost for skill frontmatter
|
||||
- Full instructions loaded only when invoked (progressive disclosure)
|
||||
- More efficient than loading all tool definitions upfront
|
||||
|
||||
### 2. Natural Language Interface
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@ description: "Try experimental features like Endless Mode before they're release
|
||||
|
||||
# Beta Features
|
||||
|
||||
<Warning>
|
||||
**Endless Mode is experimental and not included in the stable release.** You must manually switch to the beta branch to try it. The efficiency projections below are based on theoretical modeling, not production measurements. Expect slower performance than standard mode and potential bugs.
|
||||
</Warning>
|
||||
|
||||
Claude-Mem offers a beta channel for users who want to try experimental features before they're released to the stable channel.
|
||||
|
||||
## Version Channel Switching
|
||||
@@ -77,19 +81,22 @@ Archive Memory (Transcript File):
|
||||
|
||||
This transforms O(N²) scaling into O(N) - linear instead of quadratic.
|
||||
|
||||
### Expected Results
|
||||
### Projected Results
|
||||
|
||||
Based on analysis of real sessions:
|
||||
Based on theoretical modeling (not production measurements):
|
||||
|
||||
- **Token savings**: ~95% reduction in context window usage
|
||||
- **Efficiency gain**: ~20x more tool uses before context exhaustion
|
||||
- **Token savings**: Significant reduction in context window usage
|
||||
- **Efficiency gain**: More tool uses before context exhaustion
|
||||
- **Quality preservation**: Observations cache the synthesis result, so no information is lost
|
||||
|
||||
### Caveats
|
||||
### Important Caveats
|
||||
|
||||
Endless Mode is experimental:
|
||||
Endless Mode is experimental and has significant limitations:
|
||||
|
||||
- **Adds latency** - Blocking hooks wait for observation generation (60-90s per tool use)
|
||||
- **Not in stable release** - You must manually switch to the beta branch to use this feature
|
||||
- **Still in development** - May have bugs, breaking changes, or incomplete functionality
|
||||
- **Slower than standard mode** - Blocking observation generation adds latency to each tool use
|
||||
- **Theoretical projections** - The efficiency claims above are based on simulations, not real-world production data
|
||||
- **Requires working database** - Observations must save successfully for transformation
|
||||
- **New architecture** - Less battle-tested than standard mode
|
||||
|
||||
|
||||
@@ -179,7 +179,9 @@ Claude-Mem supports switching between stable and beta versions via the web viewe
|
||||
|
||||
**Your memory data is preserved** when switching versions. Only the plugin code changes.
|
||||
|
||||
See [Beta Features](beta-features) for details on what's available in beta.
|
||||
<Note>
|
||||
Endless Mode is experimental and slower than standard mode. See [Beta Features](beta-features) for full details and important limitations.
|
||||
</Note>
|
||||
|
||||
## Worker Service Management
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
"usage/claude-desktop",
|
||||
"usage/private-tags",
|
||||
"usage/export-import",
|
||||
"beta-features"
|
||||
"beta-features",
|
||||
"endless-mode"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: "Endless Mode (Beta)"
|
||||
description: "Experimental biomimetic memory architecture for extended sessions"
|
||||
---
|
||||
|
||||
# Current State of Endless Mode
|
||||
|
||||
## Core Concept
|
||||
|
||||
Endless Mode is a **biomimetic memory architecture** that solves Claude's context window exhaustion problem. Instead of keeping full tool outputs in the context window (O(N²) complexity), it:
|
||||
|
||||
- Captures compressed observations after each tool use
|
||||
- Replaces transcripts with low token summaries
|
||||
- Achieves O(N) linear complexity
|
||||
- Maintains two-tier memory: working memory (compressed) + archive memory (full transcript on disk, maintained by default claude code functionality)
|
||||
|
||||
## Implementation Status
|
||||
|
||||
**Status**: FUNCTIONAL BUT EXPERIMENTAL
|
||||
|
||||
**Current Branch**: `beta/endless-mode` (ahead of main)
|
||||
|
||||
**Recent Activity**:
|
||||
- Merged main branch changes
|
||||
- Resolved merge conflicts in save-hook, SessionStore, SessionRoutes
|
||||
- Updated documentation to remove misleading token reduction claims
|
||||
- Added important caveats about beta status
|
||||
|
||||
## Key Architecture Components
|
||||
|
||||
1. **Pre-Tool-Use Hook** - Tracks tool execution start, sends tool_use_id to worker
|
||||
2. **Save Hook (PostToolUse)** - **CRITICAL**: Blocks until observation is generated (110s timeout), injects compressed observation back into context
|
||||
3. **SessionManager.waitForNextObservation()** - Event-driven wait mechanism (no polling)
|
||||
4. **SDKAgent** - Generates observations via Agent SDK, emits completion events
|
||||
5. **Database** - Added `tool_use_id` column for observation correlation
|
||||
|
||||
## Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"CLAUDE_MEM_ENDLESS_MODE": "false", // Default: disabled
|
||||
"CLAUDE_MEM_ENDLESS_WAIT_TIMEOUT_MS": "90000" // 90 second timeout
|
||||
}
|
||||
```
|
||||
|
||||
**Enable via**: Manual checkout of beta branch (see instructions below)
|
||||
|
||||
## Flow
|
||||
|
||||
```
|
||||
Tool Executes → Pre-Hook (track ID) → Tool Completes →
|
||||
Save-Hook (BLOCKS) → Worker processes → SDK generates observation →
|
||||
Event fired → Hook receives observation → Injects markdown →
|
||||
Clears input → Context reduced
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
From the documentation:
|
||||
- ⚠️ **Slower than standard mode** - Blocking adds latency
|
||||
- ⚠️ **Still in development** - May have bugs
|
||||
- ⚠️ **Not battle-tested** - New architecture
|
||||
- ⚠️ **Theoretical projections** - Efficiency gains not yet validated in production
|
||||
|
||||
## What's Working
|
||||
|
||||
- ✅ Synchronous observation injection
|
||||
- ✅ Event-driven wait mechanism
|
||||
- ✅ Token reduction via input clearing
|
||||
- ✅ Database schema with tool_use_id
|
||||
- ✅ Web UI for version switching
|
||||
- ✅ Graceful timeout fallbacks
|
||||
|
||||
## What's Not Ready
|
||||
|
||||
- ❌ Production validation of token savings
|
||||
- ❌ Comprehensive test coverage
|
||||
- ❌ Stable channel release
|
||||
- ❌ Performance benchmarks
|
||||
- ❌ Long-running session data
|
||||
|
||||
## How to Try Endless Mode
|
||||
|
||||
Endless Mode is currently only available on the beta branch. To try it:
|
||||
|
||||
```bash
|
||||
# Navigate to your claude-mem installation
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack/
|
||||
|
||||
# Checkout the beta branch
|
||||
git checkout beta/endless-mode
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Restart the worker
|
||||
npm run worker:restart
|
||||
```
|
||||
|
||||
**To return to stable:**
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack/
|
||||
git checkout main
|
||||
npm install
|
||||
npm run worker:restart
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
The implementation is architecturally complete and functional, but remains experimental pending production validation of the theoretical efficiency gains.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "7.2.3",
|
||||
"version": "7.3.0",
|
||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||
"keywords": [
|
||||
"claude",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "7.2.3",
|
||||
"version": "7.3.0",
|
||||
"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": "7.2.3",
|
||||
"version": "7.3.0",
|
||||
"private": true,
|
||||
"description": "Runtime dependencies for claude-mem bundled hooks",
|
||||
"type": "module",
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -195,11 +195,6 @@ export function ContextSettingsModal({
|
||||
}: ContextSettingsModalProps) {
|
||||
const [formState, setFormState] = useState<Settings>(settings);
|
||||
|
||||
// MCP toggle state
|
||||
const [mcpEnabled, setMcpEnabled] = useState(true);
|
||||
const [mcpToggling, setMcpToggling] = useState(false);
|
||||
const [mcpStatus, setMcpStatus] = useState('');
|
||||
|
||||
// Create debounced save function
|
||||
const debouncedSave = useCallback(
|
||||
debounce((newSettings: Settings) => {
|
||||
@@ -213,14 +208,6 @@ export function ContextSettingsModal({
|
||||
setFormState(settings);
|
||||
}, [settings]);
|
||||
|
||||
// Fetch MCP status on mount
|
||||
useEffect(() => {
|
||||
fetch('/api/mcp/status')
|
||||
.then(res => res.json())
|
||||
.then(data => setMcpEnabled(data.enabled))
|
||||
.catch(error => console.error('Failed to load MCP status:', error));
|
||||
}, []);
|
||||
|
||||
// Get context preview based on current form state
|
||||
const { preview, isLoading, error, projects, selectedProject, setSelectedProject } = useContextPreview(formState);
|
||||
|
||||
@@ -254,36 +241,6 @@ export function ContextSettingsModal({
|
||||
updateSetting(key, values.join(','));
|
||||
}, [updateSetting]);
|
||||
|
||||
// Handle MCP toggle
|
||||
const handleMcpToggle = async (enabled: boolean) => {
|
||||
setMcpToggling(true);
|
||||
setMcpStatus('Toggling...');
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/mcp/toggle', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
setMcpEnabled(result.enabled);
|
||||
setMcpStatus('Updated (restart to apply)');
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
} else {
|
||||
setMcpStatus(`Error: ${result.error}`);
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
}
|
||||
} catch (err) {
|
||||
setMcpStatus(`Error: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
} finally {
|
||||
setMcpToggling(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle ESC key
|
||||
useEffect(() => {
|
||||
const handleEsc = (e: KeyboardEvent) => {
|
||||
@@ -521,14 +478,6 @@ export function ContextSettingsModal({
|
||||
</FormField>
|
||||
|
||||
<div className="toggle-group" style={{ marginTop: '12px' }}>
|
||||
<ToggleSwitch
|
||||
id="mcp-enabled"
|
||||
label="MCP search server"
|
||||
description={mcpStatus || "Enable Model Context Protocol search"}
|
||||
checked={mcpEnabled}
|
||||
onChange={handleMcpToggle}
|
||||
disabled={mcpToggling}
|
||||
/>
|
||||
<ToggleSwitch
|
||||
id="show-last-summary"
|
||||
label="Include last summary"
|
||||
|
||||
@@ -1,428 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Settings, Stats } from '../types';
|
||||
import { DEFAULT_SETTINGS } from '../constants/settings';
|
||||
import { formatUptime, formatBytes } from '../utils/formatters';
|
||||
|
||||
interface SidebarProps {
|
||||
isOpen: boolean;
|
||||
settings: Settings;
|
||||
stats: Stats;
|
||||
isSaving: boolean;
|
||||
saveStatus: string;
|
||||
isConnected: boolean;
|
||||
projects: string[];
|
||||
currentFilter: string;
|
||||
onFilterChange: (filter: string) => void;
|
||||
onSave: (settings: Settings) => void;
|
||||
onClose: () => void;
|
||||
onRefreshStats: () => void;
|
||||
}
|
||||
|
||||
export function Sidebar({ isOpen, settings, stats, isSaving, saveStatus, isConnected, projects, currentFilter, onFilterChange, onSave, onClose, onRefreshStats }: SidebarProps) {
|
||||
// Consolidated settings form state
|
||||
const [formState, setFormState] = useState<Settings>({
|
||||
CLAUDE_MEM_MODEL: settings.CLAUDE_MEM_MODEL || DEFAULT_SETTINGS.CLAUDE_MEM_MODEL,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATIONS: settings.CLAUDE_MEM_CONTEXT_OBSERVATIONS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATIONS,
|
||||
CLAUDE_MEM_WORKER_PORT: settings.CLAUDE_MEM_WORKER_PORT || DEFAULT_SETTINGS.CLAUDE_MEM_WORKER_PORT,
|
||||
CLAUDE_MEM_WORKER_HOST: settings.CLAUDE_MEM_WORKER_HOST || DEFAULT_SETTINGS.CLAUDE_MEM_WORKER_HOST,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS: settings.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS: settings.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: settings.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: settings.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS,
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: settings.CLAUDE_MEM_CONTEXT_FULL_COUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_COUNT,
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: settings.CLAUDE_MEM_CONTEXT_FULL_FIELD || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_FIELD,
|
||||
CLAUDE_MEM_CONTEXT_SESSION_COUNT: settings.CLAUDE_MEM_CONTEXT_SESSION_COUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SESSION_COUNT,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE,
|
||||
});
|
||||
|
||||
// MCP toggle state (separate from settings)
|
||||
const [mcpEnabled, setMcpEnabled] = useState(true);
|
||||
const [mcpToggling, setMcpToggling] = useState(false);
|
||||
const [mcpStatus, setMcpStatus] = useState('');
|
||||
|
||||
// Helper to update form state
|
||||
const updateFormState = (field: keyof Settings, value: string) => {
|
||||
setFormState(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
// Update settings form state when settings prop changes
|
||||
useEffect(() => {
|
||||
setFormState({
|
||||
CLAUDE_MEM_MODEL: settings.CLAUDE_MEM_MODEL || DEFAULT_SETTINGS.CLAUDE_MEM_MODEL,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATIONS: settings.CLAUDE_MEM_CONTEXT_OBSERVATIONS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATIONS,
|
||||
CLAUDE_MEM_WORKER_PORT: settings.CLAUDE_MEM_WORKER_PORT || DEFAULT_SETTINGS.CLAUDE_MEM_WORKER_PORT,
|
||||
CLAUDE_MEM_WORKER_HOST: settings.CLAUDE_MEM_WORKER_HOST || DEFAULT_SETTINGS.CLAUDE_MEM_WORKER_HOST,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS: settings.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS: settings.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: settings.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: settings.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS,
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: settings.CLAUDE_MEM_CONTEXT_FULL_COUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_COUNT,
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: settings.CLAUDE_MEM_CONTEXT_FULL_FIELD || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_FIELD,
|
||||
CLAUDE_MEM_CONTEXT_SESSION_COUNT: settings.CLAUDE_MEM_CONTEXT_SESSION_COUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SESSION_COUNT,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE,
|
||||
});
|
||||
}, [settings]);
|
||||
|
||||
// Fetch MCP status on mount
|
||||
useEffect(() => {
|
||||
fetch('/api/mcp/status')
|
||||
.then(res => res.json())
|
||||
.then(data => setMcpEnabled(data.enabled))
|
||||
.catch(error => console.error('Failed to load MCP status:', error));
|
||||
}, []);
|
||||
|
||||
// Refresh stats when sidebar opens
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
onRefreshStats();
|
||||
}
|
||||
}, [isOpen, onRefreshStats]);
|
||||
|
||||
const handleSave = () => {
|
||||
onSave(formState);
|
||||
};
|
||||
|
||||
const handleMcpToggle = async (enabled: boolean) => {
|
||||
setMcpToggling(true);
|
||||
setMcpStatus('Toggling...');
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/mcp/toggle', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
setMcpEnabled(result.enabled);
|
||||
setMcpStatus('✓ Updated (restart Claude Code to apply)');
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
} else {
|
||||
setMcpStatus(`✗ Error: ${result.error}`);
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
}
|
||||
} catch (error) {
|
||||
setMcpStatus(`✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
setTimeout(() => setMcpStatus(''), 3000);
|
||||
} finally {
|
||||
setMcpToggling(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`sidebar ${isOpen ? 'open' : ''}`}>
|
||||
<div className="sidebar-header">
|
||||
<h1>Settings</h1>
|
||||
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
|
||||
<span className={`status-dot ${isConnected ? 'connected' : ''}`} />
|
||||
<span style={{ fontSize: '11px', opacity: 0.5, fontWeight: 300 }}>{isConnected ? 'Connected' : 'Disconnected'}</span>
|
||||
</div>
|
||||
<button onClick={handleSave} disabled={isSaving}>
|
||||
{isSaving ? 'Saving...' : 'Save'}
|
||||
</button>
|
||||
<button
|
||||
onClick={onClose}
|
||||
title="Close settings"
|
||||
style={{
|
||||
background: 'transparent',
|
||||
border: '1px solid #404040',
|
||||
padding: '8px',
|
||||
width: '36px',
|
||||
height: '36px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="https://discord.gg/J4wttp9vDu"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="sidebar-community-btn"
|
||||
title="Join our Discord community"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" style={{ marginRight: '6px' }}>
|
||||
<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>
|
||||
<span>Community</span>
|
||||
</a>
|
||||
<div className="sidebar-social-links">
|
||||
<a
|
||||
href="https://docs.claude-mem.ai"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="Documentation"
|
||||
className="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://github.com/thedotmack/claude-mem/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="GitHub"
|
||||
className="icon-link"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://x.com/Claude_Memory"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="X (Twitter)"
|
||||
className="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>
|
||||
</div>
|
||||
<div className="sidebar-project-filter">
|
||||
<label htmlFor="sidebar-project-select">Filter by Project</label>
|
||||
<select
|
||||
id="sidebar-project-select"
|
||||
value={currentFilter}
|
||||
onChange={e => onFilterChange(e.target.value)}
|
||||
>
|
||||
<option value="">All Projects</option>
|
||||
{projects.map(project => (
|
||||
<option key={project} value={project}>{project}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="stats-scroll">
|
||||
|
||||
<div className="settings-section">
|
||||
<h3>Environment Variables</h3>
|
||||
<div className="form-group">
|
||||
<label htmlFor="model">CLAUDE_MEM_MODEL</label>
|
||||
<div className="setting-description">
|
||||
Model used for AI compression of tool observations. Haiku is fast and cheap, Sonnet offers better quality, Opus is most capable but expensive.
|
||||
</div>
|
||||
<select
|
||||
id="model"
|
||||
value={formState.CLAUDE_MEM_MODEL}
|
||||
onChange={e => updateFormState('CLAUDE_MEM_MODEL', e.target.value)}
|
||||
>
|
||||
{/* Shorthand names forward to latest model version */}
|
||||
<option value="haiku">haiku</option>
|
||||
<option value="sonnet">sonnet</option>
|
||||
<option value="opus">opus</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="contextObs">CLAUDE_MEM_CONTEXT_OBSERVATIONS</label>
|
||||
<div className="setting-description">
|
||||
Number of recent observations to inject at session start. Higher values provide more context but increase token usage. Default: 50
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
id="contextObs"
|
||||
min="1"
|
||||
max="200"
|
||||
value={formState.CLAUDE_MEM_CONTEXT_OBSERVATIONS}
|
||||
onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_OBSERVATIONS', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="workerPort">CLAUDE_MEM_WORKER_PORT</label>
|
||||
<div className="setting-description">
|
||||
Port number for the background worker service. Change only if port 37777 conflicts with another service.
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
id="workerPort"
|
||||
min="1024"
|
||||
max="65535"
|
||||
value={formState.CLAUDE_MEM_WORKER_PORT}
|
||||
onChange={e => updateFormState('CLAUDE_MEM_WORKER_PORT', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="workerHost">CLAUDE_MEM_WORKER_HOST</label>
|
||||
<div className="setting-description">
|
||||
IP address to bind the worker service. Use 127.0.0.1 (default) for local-only access, or 0.0.0.0 for remote access on servers.
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
id="workerHost"
|
||||
value={formState.CLAUDE_MEM_WORKER_HOST}
|
||||
onChange={e => updateFormState('CLAUDE_MEM_WORKER_HOST', e.target.value)}
|
||||
placeholder="127.0.0.1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Token Economics Display */}
|
||||
<div className="form-group">
|
||||
<label>Token Economics Display</label>
|
||||
<div className="setting-description">
|
||||
Choose which token metrics to show in session start context.
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS', e.target.checked ? 'true' : 'false')} />
|
||||
Show read tokens
|
||||
</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS', e.target.checked ? 'true' : 'false')} />
|
||||
Show work tokens
|
||||
</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT', e.target.checked ? 'true' : 'false')} />
|
||||
Show savings amount
|
||||
</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT', e.target.checked ? 'true' : 'false')} />
|
||||
Show savings percentage
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Display Configuration */}
|
||||
<div className="form-group">
|
||||
<label>Display Configuration</label>
|
||||
<div className="setting-description">
|
||||
Control how observations are displayed in the timeline.
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '8px' }}>
|
||||
<div>
|
||||
<label htmlFor="fullCount" style={{ display: 'block', marginBottom: '4px', fontSize: '13px' }}>
|
||||
Full observation count (0-20)
|
||||
</label>
|
||||
<input type="number" id="fullCount" min="0" max="20" value={formState.CLAUDE_MEM_CONTEXT_FULL_COUNT} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_FULL_COUNT', e.target.value)} style={{ width: '100%' }} />
|
||||
<div style={{ fontSize: '12px', color: '#999', marginTop: '4px' }}>
|
||||
Number of most recent observations to show with full details
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="fullField" style={{ display: 'block', marginBottom: '4px', fontSize: '13px' }}>
|
||||
Full observation field
|
||||
</label>
|
||||
<select id="fullField" value={formState.CLAUDE_MEM_CONTEXT_FULL_FIELD} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_FULL_FIELD', e.target.value)} style={{ width: '100%' }}>
|
||||
<option value="narrative">Narrative</option>
|
||||
<option value="facts">Facts</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="sessionCount" style={{ display: 'block', marginBottom: '4px', fontSize: '13px' }}>
|
||||
Session summary count (1-50)
|
||||
</label>
|
||||
<input type="number" id="sessionCount" min="1" max="50" value={formState.CLAUDE_MEM_CONTEXT_SESSION_COUNT} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SESSION_COUNT', e.target.value)} style={{ width: '100%' }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Feature Toggles */}
|
||||
<div className="form-group">
|
||||
<label>Context Features</label>
|
||||
<div className="setting-description">
|
||||
Toggle additional features in session start context.
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY', e.target.checked ? 'true' : 'false')} />
|
||||
Show last session summary
|
||||
</label>
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input type="checkbox" checked={formState.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE === 'true'} onChange={e => updateFormState('CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE', e.target.checked ? 'true' : 'false')} />
|
||||
Include last session message
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{saveStatus && (
|
||||
<div className="save-status">{saveStatus}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="settings-section">
|
||||
<h3>MCP Search Server</h3>
|
||||
<div className="form-group">
|
||||
<label htmlFor="mcpEnabled" style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="mcpEnabled"
|
||||
checked={mcpEnabled}
|
||||
onChange={e => handleMcpToggle(e.target.checked)}
|
||||
disabled={mcpToggling}
|
||||
style={{ cursor: mcpToggling ? 'not-allowed' : 'pointer' }}
|
||||
/>
|
||||
Enable MCP Search Server
|
||||
</label>
|
||||
<div className="setting-description">
|
||||
claude-mem suggests using skill-based search (saves ~2,500 tokens at session start), but some users prefer MCP. Disable to only use skill-based search. Requires Claude Code restart to apply changes.
|
||||
</div>
|
||||
{mcpStatus && (
|
||||
<div className="save-status">{mcpStatus}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settings-section">
|
||||
<h3>Worker Stats</h3>
|
||||
<div className="stats-grid">
|
||||
<div className="stat">
|
||||
<div className="stat-label">Version</div>
|
||||
<div className="stat-value">{stats.worker?.version || '-'}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">Uptime</div>
|
||||
<div className="stat-value">{formatUptime(stats.worker?.uptime)}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">Active Sessions</div>
|
||||
<div className="stat-value">{stats.worker?.activeSessions || '0'}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">SSE Clients</div>
|
||||
<div className="stat-value">{stats.worker?.sseClients || '0'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settings-section">
|
||||
<h3>Database Stats</h3>
|
||||
<div className="stats-grid">
|
||||
<div className="stat">
|
||||
<div className="stat-label">DB Size</div>
|
||||
<div className="stat-value">{formatBytes(stats.database?.size)}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">Observations</div>
|
||||
<div className="stat-value">{stats.database?.observations || '0'}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">Sessions</div>
|
||||
<div className="stat-value">{stats.database?.sessions || '0'}</div>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="stat-label">Summaries</div>
|
||||
<div className="stat-value">{stats.database?.summaries || '0'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user