f38b5b85bc
* docs: add investigation reports for 5 open GitHub issues Comprehensive analysis of issues #543, #544, #545, #555, and #557: - #557: settings.json not generated, module loader error (node/bun mismatch) - #555: Windows hooks not executing, hasIpc always false - #545: formatTool crashes on non-JSON tool_input strings - #544: mem-search skill hint shown incorrectly to Claude Code users - #543: /claude-mem slash command unavailable despite installation Each report includes root cause analysis, affected files, and proposed fixes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(logger): handle non-JSON tool_input in formatTool (#545) Wrap JSON.parse in try-catch to handle raw string inputs (e.g., Bash commands) that aren't valid JSON. Falls back to using the string as-is. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(context): update mem-search hint to reference MCP tools (#544) Update hint messages to reference MCP tools (search, get_observations) instead of the deprecated "mem-search skill" terminology. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(settings): auto-create settings.json on first load (#557, #543) When settings.json doesn't exist, create it with defaults instead of returning in-memory defaults. Creates parent directory if needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(hooks): use bun runtime for hooks except smart-install (#557) Change hook commands from node to bun since hooks use bun:sqlite. Keep smart-install.js on node since it bootstraps bun installation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: rebuild plugin scripts * docs: clarify that build artifacts must be committed * fix(docs): update build artifacts directory reference in CLAUDE.md * test: add test coverage for PR #558 fixes - Fix 2 failing tests: update "mem-search skill" → "MCP tools" expectations - Add 56 tests for formatTool() JSON.parse crash fix (Issue #545) - Add 27 tests for settings.json auto-creation (Issue #543) Test coverage includes: - formatTool: JSON parsing, raw strings, objects, null/undefined, all tool types - Settings: file creation, directory creation, schema migration, edge cases 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(tests): clean up flaky tests and fix circular dependency Phase 1 of test quality improvements: - Delete 6 harmful/worthless test files that used problematic mock.module() patterns or tested implementation details rather than behavior: - context-builder.test.ts (tested internal implementation) - export-types.test.ts (fragile mock patterns) - smart-install.test.ts (shell script testing antipattern) - session_id_refactor.test.ts (outdated, tested refactoring itself) - validate_sql_update.test.ts (one-time migration validation) - observation-broadcaster.test.ts (excessive mocking) - Fix circular dependency between logger.ts and SettingsDefaultsManager.ts by using late binding pattern - logger now lazily loads settings - Refactor mock.module() to spyOn() in several test files for more maintainable and less brittle tests: - observation-compiler.test.ts - gemini_agent.test.ts - error-handler.test.ts - server.test.ts - response-processor.test.ts All 649 tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(tests): phase 2 - reduce mock-heavy tests and improve focus - Remove mock-heavy query tests from observation-compiler.test.ts, keep real buildTimeline tests - Convert session_id_usage_validation.test.ts from 477 to 178 lines of focused smoke tests - Remove tests for language built-ins from worker-spawn.test.ts (JSON.parse, array indexing) - Rename logger-coverage.test.ts to logger-usage-standards.test.ts for clarity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(tests): phase 3 - add JSDoc mock justification to test files Document mock usage rationale in 5 test files to improve maintainability: - error-handler.test.ts: Express req/res mocks, logger spies (~11%) - fallback-error-handler.test.ts: Zero mocks, pure function tests - session-cleanup-helper.test.ts: Session fixtures, worker mocks (~19%) - hook-constants.test.ts: process.platform mock for Windows tests (~12%) - session_store.test.ts: Zero mocks, real SQLite :memory: database Part of ongoing effort to document mock justifications per TESTING.md guidelines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(integration): phase 5 - add 72 tests for critical coverage gaps Add comprehensive test coverage for previously untested areas: - tests/integration/hook-execution-e2e.test.ts (10 tests) Tests lifecycle hooks execution flow and context propagation - tests/integration/worker-api-endpoints.test.ts (19 tests) Tests all worker service HTTP endpoints without heavy mocking - tests/integration/chroma-vector-sync.test.ts (16 tests) Tests vector embedding synchronization with ChromaDB - tests/utils/tag-stripping.test.ts (27 tests) Tests privacy tag stripping utilities for both <private> and <meta-observation> tags All tests use real implementations where feasible, following the project's testing philosophy of preferring integration-style tests over unit tests with extensive mocking. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * context update * docs: add comment linking DEFAULT_DATA_DIR locations Added NOTE comment in logger.ts pointing to the canonical DEFAULT_DATA_DIR in SettingsDefaultsManager.ts. This addresses PR reviewer feedback about the fragility of having the default defined in two places to avoid circular dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
445 lines
14 KiB
Markdown
445 lines
14 KiB
Markdown
# Investigation Report: Issue #544 - mem-search Skill Hint Shown to Claude Code Users
|
|
|
|
**Date:** 2026-01-05
|
|
**Issue:** https://github.com/thedotmack/claude-mem/issues/544
|
|
**Author:** m.woelk (@neifgmbh)
|
|
**Status:** Open
|
|
|
|
---
|
|
|
|
## Issue Summary
|
|
|
|
The context footer displayed to users includes the message:
|
|
|
|
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
|
|
|
This hint is misleading because:
|
|
1. **For Claude Code users**: The "mem-search skill" terminology is confusing. In Claude Code, memory search is available through **MCP tools** (`search`, `timeline`, `get_observations`), not a "skill"
|
|
2. **For all users**: The skill directories in `plugin/skills/` are empty - no SKILL.md files exist
|
|
|
|
A second user (@niteeshm) confirmed the issue with "+1 the mem-search skill is missing."
|
|
|
|
---
|
|
|
|
## Code Location Verification
|
|
|
|
### Confirmed Locations
|
|
|
|
The message appears in **two formatters** and is rendered via **FooterRenderer.ts**:
|
|
|
|
#### 1. MarkdownFormatter.ts (line 228-234)
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts`
|
|
|
|
```typescript
|
|
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
|
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
|
return [
|
|
'',
|
|
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.`
|
|
];
|
|
}
|
|
```
|
|
|
|
#### 2. ColorFormatter.ts (line 225-231)
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts`
|
|
|
|
```typescript
|
|
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
|
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
|
return [
|
|
'',
|
|
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.${colors.reset}`
|
|
];
|
|
}
|
|
```
|
|
|
|
#### 3. Additional References in Context Instructions
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts` (lines 70-79)
|
|
|
|
```typescript
|
|
export function renderMarkdownContextIndex(): string[] {
|
|
return [
|
|
`**Context Index:** This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.`,
|
|
'',
|
|
`When you need implementation details, rationale, or debugging context:`,
|
|
`- Use the mem-search skill to fetch full observations on-demand`,
|
|
`- Critical types ( bugfix, decision) often need detailed fetching`,
|
|
`- Trust this index over re-reading code for past decisions and learnings`,
|
|
''
|
|
];
|
|
}
|
|
```
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts` (lines 72-81)
|
|
|
|
```typescript
|
|
export function renderColorContextIndex(): string[] {
|
|
return [
|
|
`${colors.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${colors.reset}`,
|
|
'',
|
|
`${colors.dim}When you need implementation details, rationale, or debugging context:${colors.reset}`,
|
|
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
|
...
|
|
];
|
|
}
|
|
```
|
|
|
|
#### 4. Footer Rendering Logic
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/sections/FooterRenderer.ts`
|
|
|
|
```typescript
|
|
export function renderFooter(
|
|
economics: TokenEconomics,
|
|
config: ContextConfig,
|
|
useColors: boolean
|
|
): string[] {
|
|
// Only show footer if we have savings to display
|
|
if (!shouldShowContextEconomics(config) || economics.totalDiscoveryTokens <= 0 || economics.savings <= 0) {
|
|
return [];
|
|
}
|
|
|
|
if (useColors) {
|
|
return Color.renderColorFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
|
}
|
|
return Markdown.renderMarkdownFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Detection Analysis
|
|
|
|
### Current State: No Detection Exists
|
|
|
|
**Finding:** Claude-mem does **NOT** currently differentiate between Claude Code and Claude Desktop environments.
|
|
|
|
**Evidence:**
|
|
1. Searched entire `src/` directory for environment detection patterns:
|
|
- `claude.?code`, `claude.?desktop`, `isClaudeCode`, `isClaudeDesktop`, `environment`
|
|
- Found 22 files, but none contain Claude Code vs Claude Desktop detection logic
|
|
|
|
2. Hook input analysis (`SessionStartInput` in `context-hook.ts`):
|
|
```typescript
|
|
export interface SessionStartInput {
|
|
session_id: string;
|
|
transcript_path: string;
|
|
cwd: string;
|
|
hook_event_name?: string;
|
|
}
|
|
```
|
|
No environment identifier is passed to hooks.
|
|
|
|
3. The `ContextConfig` type has no environment field:
|
|
```typescript
|
|
export interface ContextConfig {
|
|
totalObservationCount: number;
|
|
fullObservationCount: number;
|
|
sessionCount: number;
|
|
showReadTokens: boolean;
|
|
showWorkTokens: boolean;
|
|
// ... no environment field
|
|
}
|
|
```
|
|
|
|
### Why Detection Would Be Difficult
|
|
|
|
Claude Code and Claude Desktop both:
|
|
- Use the same plugin system (hooks)
|
|
- Use the same MCP server configuration
|
|
- Receive the same hook input structure
|
|
|
|
**Potential Detection Methods:**
|
|
1. **Process name/parent** - Check if running under "claude-code" or "Claude Desktop" process
|
|
2. **Environment variables** - Claude may set different env vars (needs research)
|
|
3. **MCP config location** - Different config paths for each client
|
|
4. **User agent/client header** - If available in MCP protocol
|
|
|
|
---
|
|
|
|
## Skill Availability Analysis
|
|
|
|
### What Actually Exists
|
|
|
|
#### Claude Code MCP Tools (via `.mcp.json`)
|
|
|
|
**File:** `/Users/alexnewman/Scripts/claude-mem/plugin/.mcp.json`
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"mcp-search": {
|
|
"type": "stdio",
|
|
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/mcp-server.cjs"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Available MCP Tools** (from `mcp-server.ts`):
|
|
1. `search` - Step 1: Search memory index
|
|
2. `timeline` - Step 2: Get context around results
|
|
3. `get_observations` - Step 3: Fetch full details by IDs
|
|
4. `__IMPORTANT` - Workflow documentation
|
|
|
|
**These tools ARE available in Claude Code** via MCP protocol.
|
|
|
|
#### Claude Desktop Setup (Manual)
|
|
|
|
From documentation (`docs/public/usage/claude-desktop.mdx`):
|
|
- Requires manual MCP server configuration in `claude_desktop_config.json`
|
|
- Uses the same MCP server and tools as Claude Code
|
|
- Documentation refers to this as the "mem-search skill"
|
|
|
|
#### Plugin Skills Directory (Empty)
|
|
|
|
**Path:** `/Users/alexnewman/Scripts/claude-mem/plugin/skills/`
|
|
|
|
```
|
|
skills/
|
|
claude-mem-settings/ (empty)
|
|
mem-search/
|
|
operations/ (empty)
|
|
principles/ (empty)
|
|
search/
|
|
operations/ (empty)
|
|
troubleshoot/
|
|
operations/ (empty)
|
|
```
|
|
|
|
**Finding:** All skill directories are empty - no `SKILL.md` files exist.
|
|
|
|
### Terminology Confusion
|
|
|
|
| What Users See | What Actually Exists |
|
|
|---------------|---------------------|
|
|
| "mem-search skill" | MCP tools (`search`, `timeline`, `get_observations`) |
|
|
| "skill" | Empty directory structures in `plugin/skills/` |
|
|
| "skill to fetch observations" | `get_observations` MCP tool |
|
|
|
|
**The "skill" terminology is a legacy artifact** from an earlier architecture. The current system uses MCP tools, not skills.
|
|
|
|
---
|
|
|
|
## Root Cause
|
|
|
|
1. **Legacy Terminology**: The footer message uses "skill" language from a previous architecture
|
|
2. **Architecture Evolution**: The search system migrated from skill-based to MCP-based (documented in `search-architecture.mdx`):
|
|
> "Skill approach... was removed in favor of streamlined MCP architecture"
|
|
3. **Incomplete Migration**: The message text was not updated when the architecture changed
|
|
4. **No Skill Files**: The skill directories exist but contain no SKILL.md files
|
|
|
|
---
|
|
|
|
## Proposed Fix Options
|
|
|
|
### Option 1: Update Message to Reference MCP Tools (Recommended)
|
|
|
|
**Change the message to accurately describe the MCP tools:**
|
|
|
|
**Before:**
|
|
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
|
|
|
**After:**
|
|
> "Use MCP search tools (search, timeline, get_observations) to access memories by ID."
|
|
|
|
**Files to modify:**
|
|
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
|
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
|
|
|
**Pros:**
|
|
- Accurate for both Claude Code and Claude Desktop
|
|
- No environment detection needed
|
|
- Simple change
|
|
|
|
**Cons:**
|
|
- Longer message
|
|
- Users need to know about MCP tools
|
|
|
|
### Option 2: Remove the Hint Entirely
|
|
|
|
**Simply remove the "Use the mem-search skill..." portion of the message.**
|
|
|
|
**Before:**
|
|
> "Access 5k tokens of past research & decisions for just 1,234t. Use the mem-search skill to access memories by ID instead of re-reading files."
|
|
|
|
**After:**
|
|
> "Access 5k tokens of past research & decisions for just 1,234t."
|
|
|
|
**Files to modify:**
|
|
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
|
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
|
|
|
**Pros:**
|
|
- Simplest fix
|
|
- No confusion about terminology
|
|
- Cleaner footer
|
|
|
|
**Cons:**
|
|
- Loses the helpful hint about memory search
|
|
- Users may not know about MCP tools
|
|
|
|
### Option 3: Conditional Message Based on Environment Detection
|
|
|
|
**Implement environment detection and show different messages:**
|
|
|
|
```typescript
|
|
export function renderFooter(economics: TokenEconomics, config: ContextConfig, useColors: boolean): string[] {
|
|
const isClaudeCode = detectClaudeCodeEnvironment();
|
|
const searchHint = isClaudeCode
|
|
? "Use MCP search tools to access memories by ID."
|
|
: "Use the mem-search skill to access memories by ID.";
|
|
// ...
|
|
}
|
|
```
|
|
|
|
**Files to modify:**
|
|
- Create new utility: `src/utils/environment-detection.ts`
|
|
- `src/services/context/sections/FooterRenderer.ts`
|
|
- `src/services/context/formatters/MarkdownFormatter.ts`
|
|
- `src/services/context/formatters/ColorFormatter.ts`
|
|
|
|
**Pros:**
|
|
- Context-appropriate messaging
|
|
- Maintains helpful hint
|
|
|
|
**Cons:**
|
|
- Complex to implement
|
|
- May be fragile (environment detection methods could break)
|
|
- More maintenance burden
|
|
- Unclear how to reliably detect environment
|
|
|
|
### Option 4: Implement Actual Skills for Claude Code
|
|
|
|
**Create SKILL.md files in `plugin/skills/mem-search/`:**
|
|
|
|
**Path:** `plugin/skills/mem-search/SKILL.md`
|
|
```markdown
|
|
---
|
|
name: mem-search
|
|
description: Search claude-mem memory database using MCP tools
|
|
---
|
|
|
|
# Memory Search
|
|
|
|
Use MCP tools to search your project memory...
|
|
```
|
|
|
|
**Pros:**
|
|
- Makes the message accurate
|
|
- Provides better user guidance
|
|
- Consistent with skill-based architecture
|
|
|
|
**Cons:**
|
|
- Skills may be deprecated in favor of MCP
|
|
- More files to maintain
|
|
- May confuse the architecture (skills wrapping MCP tools)
|
|
|
|
---
|
|
|
|
## Implementation Recommendation
|
|
|
|
**Recommended: Option 1 (Update Message to Reference MCP Tools)**
|
|
|
|
### Rationale
|
|
|
|
1. **Accuracy**: MCP tools are the actual mechanism, not skills
|
|
2. **Simplicity**: Single source of truth, no environment detection needed
|
|
3. **Documentation Alignment**: Matches the architecture documentation
|
|
4. **Low Risk**: Minimal code changes, no new systems
|
|
|
|
### Specific Changes
|
|
|
|
#### MarkdownFormatter.ts
|
|
|
|
**Line 75** (Context Index section):
|
|
```typescript
|
|
// Before:
|
|
`- Use the mem-search skill to fetch full observations on-demand`,
|
|
|
|
// After:
|
|
`- Use MCP tools (search, get_observations) to fetch full observations on-demand`,
|
|
```
|
|
|
|
**Lines 228-234** (Footer):
|
|
```typescript
|
|
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
|
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
|
return [
|
|
'',
|
|
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.`
|
|
];
|
|
}
|
|
```
|
|
|
|
#### ColorFormatter.ts
|
|
|
|
**Line 77** (Context Index section):
|
|
```typescript
|
|
// Before:
|
|
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
|
|
|
// After:
|
|
`${colors.dim} - Use MCP tools (search, get_observations) to fetch full observations on-demand${colors.reset}`,
|
|
```
|
|
|
|
**Lines 225-231** (Footer):
|
|
```typescript
|
|
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
|
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
|
return [
|
|
'',
|
|
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.${colors.reset}`
|
|
];
|
|
}
|
|
```
|
|
|
|
### Testing
|
|
|
|
1. Rebuild plugin: `npm run build-and-sync`
|
|
2. Restart Claude Code
|
|
3. Verify footer message appears correctly
|
|
4. Verify context index instructions appear correctly
|
|
|
|
---
|
|
|
|
## Additional Considerations
|
|
|
|
### Empty Skill Directories
|
|
|
|
The empty `plugin/skills/` directories should be addressed separately:
|
|
- Either remove them (if skills are deprecated)
|
|
- Or populate them with SKILL.md files (if skills are still supported)
|
|
|
|
This is a **separate issue** from the message text.
|
|
|
|
### Documentation Updates
|
|
|
|
If Option 1 is implemented, documentation should also be reviewed:
|
|
- `docs/public/usage/claude-desktop.mdx` references "mem-search skill"
|
|
- `README.md` mentions "Skill-Based Search"
|
|
- Various i18n README files
|
|
|
|
Consider creating a follow-up issue for documentation consistency.
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
| Aspect | Finding |
|
|
|--------|---------|
|
|
| **Issue Valid?** | Yes - message is misleading |
|
|
| **Location Verified?** | Yes - 4 locations in 2 formatters |
|
|
| **Environment Detection?** | Does not exist |
|
|
| **Skill Files?** | Empty directories, no SKILL.md |
|
|
| **MCP Tools Available?** | Yes - in both Claude Code and Desktop |
|
|
| **Recommended Fix** | Option 1: Update message to reference MCP tools |
|
|
| **Complexity** | Low - 4 string changes |
|
|
| **Risk** | Low - cosmetic text change |
|
|
|
|
---
|
|
|
|
*Report prepared for GitHub Issue #544*
|