fix: Claude Code 2.1.1 compatibility + log-level audit + path validation fixes (#614)

* Refactor CLAUDE.md and related files for December 2025 updates

- Updated CLAUDE.md in src/services/worker with new entries for December 2025, including changes to Search.ts, GeminiAgent.ts, SDKAgent.ts, and SessionManager.ts.
- Revised CLAUDE.md in src/shared to reflect updates and new entries for December 2025, including paths.ts and worker-utils.ts.
- Modified hook-constants.ts to clarify exit codes and their behaviors.
- Added comprehensive hooks reference documentation for Claude Code, detailing usage, events, and examples.
- Created initial CLAUDE.md files in various directories to track recent activity.

* fix: Merge user-message-hook output into context-hook hookSpecificOutput

- Add footer message to additionalContext in context-hook.ts
- Remove user-message-hook from SessionStart hooks array
- Fixes issue where stderr+exit(1) approach was silently discarded

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

* Update logs and documentation for recent plugin and worker service changes

- Added detailed logs for worker service activities from Dec 10, 2025 to Jan 7, 2026, including initialization patterns, cleanup confirmations, and diagnostic logging.
- Updated plugin documentation with recent activities, including plugin synchronization and configuration changes from Dec 3, 2025 to Jan 7, 2026.
- Enhanced the context hook and worker service logs to reflect improvements and fixes in the plugin architecture.
- Documented the migration and verification processes for the Claude memory system and its integration with the marketplace.

* Refactor hooks architecture and remove deprecated user-message-hook

- Updated hook configurations in CLAUDE.md and hooks.json to reflect changes in session start behavior.
- Removed user-message-hook functionality as it is no longer utilized in Claude Code 2.1.0; context is now injected silently.
- Enhanced context-hook to handle session context injection without user-visible messages.
- Cleaned up documentation across multiple files to align with the new hook structure and removed references to obsolete hooks.
- Adjusted timing and command execution for hooks to improve performance and reliability.

* fix: Address PR #610 review issues

- Replace USER_MESSAGE_ONLY test with BLOCKING_ERROR test in hook-constants.test.ts
- Standardize Claude Code 2.1.0 note wording across all three documentation files
- Exclude deprecated user-message-hook.ts from logger-usage-standards test

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

* fix: Remove hardcoded fake token counts from context injection

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

* Address PR #610 review issues by fixing test files, standardizing documentation notes, and verifying code quality improvements.

* fix: Add path validation to CLAUDE.md distribution to prevent invalid directory creation

- Add isValidPathForClaudeMd() function to reject invalid paths:
  - Tilde paths (~) that Node.js doesn't expand
  - URLs (http://, https://)
  - Paths with spaces (likely command text or PR references)
  - Paths with # (GitHub issue/PR references)
  - Relative paths that escape project boundary

- Integrate validation in updateFolderClaudeMdFiles loop
- Add 6 unit tests for path validation
- Update .gitignore to prevent accidental commit of malformed directories
- Clean up existing invalid directories (~/, PR #610..., git diff..., https:)

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

* fix: Implement path validation in CLAUDE.md generation to prevent invalid directory creation

- Added `isValidPathForClaudeMd()` function to validate file paths in `src/utils/claude-md-utils.ts`.
- Integrated path validation in `updateFolderClaudeMdFiles` to skip invalid paths.
- Added 6 new unit tests in `tests/utils/claude-md-utils.test.ts` to cover various rejection cases.
- Updated `.gitignore` to prevent tracking of invalid directories.
- Cleaned up existing invalid directories in the repository.

* feat: Promote critical WARN logs to ERROR level across codebase

Comprehensive log-level audit promoting 38+ WARN messages to ERROR for
improved debugging and incident response:

- Parser: observation type errors, data contamination
- SDK/Agents: empty init responses (Gemini, OpenRouter)
- Worker/Queue: session recovery, auto-recovery failures
- Chroma: sync failures, search failures (now treated as critical)
- SQLite: search failures (primary data store)
- Session/Generator: failures, missing context
- Infrastructure: shutdown, process management failures
- File Operations: CLAUDE.md updates, config reads
- Branch Management: recovery checkout failures

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

* fix: Address PR #614 review issues

- Remove incorrectly tracked tilde-prefixed files from git
- Fix absolute path validation to check projectRoot boundaries
- Add test coverage for absolute path validation edge cases

Closes review issues:
- Issue 1: ~/ prefixed files removed from tracking
- Issue 3: Absolute paths now validated against projectRoot
- Issue 4: Added 3 new test cases for absolute path scenarios

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

* build assets and context

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-01-07 23:34:20 -05:00
committed by GitHub
parent 687146ce53
commit 2659ec3231
98 changed files with 8927 additions and 3554 deletions

View File

@@ -3,169 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 26, 2025
**adaptive-orbiting-sundae.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32927 | 10:32 PM | ⚖️ | Three-Phase Fix Plan Created for PR #448 OpenRouter Error Handling Issues | ~543 |
**floating-petting-snowglobe.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32915 | 10:08 PM | 🔵 | OpenRouter Provider PR #448 Fix Plan Loaded | ~345 |
### Dec 27, 2025
**greedy-puzzling-teapot.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33132 | 7:53 PM | ⚖️ | Session Continuity Regression Investigation and Fix Plan Created | ~567 |
**parallel-snuggling-kazoo.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33008 | 4:54 PM | ⚖️ | Auto-Restart Worker Strategy After Plugin Updates | ~514 |
**fancy-leaping-orbit.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32999 | 4:43 PM | ⚖️ | Worker Update Strategy Changed from Auto-Restart to Manual | ~265 |
| #32997 | 4:42 PM | ✅ | Implementation Plan Documented for Windows Concurrency Fix | ~597 |
### Dec 28, 2025
**scalable-exploring-wadler.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33597 | 11:14 PM | 🔵 | MCP search tool successfully retrieving mem-search to mcp-search rename history | ~361 |
**pr-458-fixes.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33291 | 3:08 PM | ✅ | Completed PR #458 Worker Lifecycle Fix Plan - Phase 6 Build Verification | ~334 |
| #33275 | 3:01 PM | 🔴 | Unix orphaned process cleanup error handling fixed | ~330 |
| #33274 | " | 🔴 | Fixed waitForProcessesExit crash when child processes exit | ~312 |
| #33273 | " | 🔴 | Added PID validation after daemon spawn to prevent invalid PID file writes | ~341 |
| #33272 | " | 🔴 | Windows taskkill error handling in orphaned process cleanup | ~266 |
**mellow-discovering-meerkat.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33262 | 2:58 PM | ✅ | PR #456 Closed and Fresh Branch Created for Worker Lifecycle Fix | ~313 |
**functional-shimmying-lake.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33257 | 2:37 PM | ✅ | Plan Simplified to Minimal Fix Approach | ~320 |
### Dec 29, 2025
**worker-executable.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33895 | 5:13 PM | 🟣 | Implemented install-time worker executable compilation | ~423 |
| #33883 | 5:11 PM | ⚖️ | Plan created for worker executable compilation strategy | ~432 |
**phased-worker-executable-plan.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33873 | 4:56 PM | ⚖️ | Worker Service Migration to Standalone Executables | ~531 |
**precious-dancing-rossum.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33872 | 4:56 PM | ⚖️ | Build-time executable strategy replaced with install-time compilation approach | ~524 |
| #33870 | 4:52 PM | ⚖️ | Migrate Worker Service from Runtime .cjs to Compiled Platform Executables | ~567 |
### Dec 30, 2025
**lively-twirling-garden.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34411 | 1:55 PM | ⚖️ | Agent SDK V2 Migration Plan Created | ~519 |
### Jan 1, 2026
**cozy-orbiting-hopper.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35485 | 9:06 PM | ⚖️ | Comprehensive error handling remediation plan completed and submitted for approval | ~555 |
| #35484 | 9:05 PM | ✅ | Quick reference checklist added for all 45 critical issues | ~390 |
| #35483 | " | ✅ | Plan implementation section replaced with practical execution guidance | ~375 |
| #35482 | " | ✅ | Verification progress metrics updated with accurate wave counts | ~313 |
| #35481 | " | ✅ | Wave 3 Group 3C scope reduced after code verification | ~341 |
| #35480 | " | ✅ | Wave 2 specific fixes detailed with exact code patterns | ~401 |
| #35479 | 9:04 PM | ✅ | Wave 2 fix pattern updated to target worst offender | ~363 |
| #35478 | " | ✅ | Plan updated with accurate Wave 2 critical path failures | ~424 |
| #35471 | 9:02 PM | ⚖️ | Systematic plan created to fix 45 critical error handling anti-patterns | ~540 |
**ticklish-humming-pixel.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35296 | 1:25 PM | ⚖️ | Revised implementation plan: Generate deterministic memory session IDs to prevent orphaned sessions | ~619 |
| #35295 | " | ⚖️ | Updated Implementation Plan - Deterministic Session ID with Immediate Persistence | ~505 |
| #35251 | 1:14 PM | ✅ | Plan updated with correct import paths for provider check functions | ~301 |
| #35246 | " | ⚖️ | Implementation plan created: Add provider check to startup-recovery mechanism | ~525 |
### Jan 2, 2026
**gleaming-imagining-cray.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36104 | 10:31 PM | ⚖️ | Database Transaction Strategy for Observation Deduplication | ~474 |
### Jan 3, 2026
**nifty-honking-goblet.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36644 | 10:59 PM | ✅ | Test Fixes Plan Updated with Logger Coverage Implementation Details | ~469 |
**glimmering-coalescing-pnueli.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36160 | 6:41 PM | ⚖️ | Final Architecture Approved: Grep-Optimized Progressive Disclosure with Named Re-Exports | ~757 |
| #36159 | 6:39 PM | ⚖️ | Phase 1 Refactor Plan Finalized: Grep-Optimized Progressive Disclosure with Named Re-Exports | ~830 |
### Jan 4, 2026
**greedy-soaring-sphinx.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36762 | 12:37 AM | ✅ | Created Implementation Plan for Four GitHub Issues | ~438 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**fix-claudemd-worktree-bug.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38005 | 9:03 PM | 🔵 | Comprehensive exploration of PR review items completed | ~438 |
| #38004 | " | 🔵 | Prior plan documented worktree bug fix with projectRoot parameter | ~416 |
**velvety-churning-globe.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37763 | 6:32 PM | 🔵 | Comprehensive test suite cleanup plan for claude-mem project | ~446 |
| #37762 | 6:31 PM | ⚖️ | Test Cleanup Plan Approved: Delete 6 Harmful Tests, Add 4 Integration Tests | ~793 |
| #37761 | 6:26 PM | ✅ | Test Cleanup Plan Updated with Detailed File Lists and Impact Summary | ~643 |
| #37760 | " | ⚖️ | Test Plan Expanded: Four New Integration Tests Added to Cleanup Scope | ~500 |
| #37759 | 6:25 PM | ⚖️ | Test Suite Cleanup Plan Created Based on Comprehensive Audit | ~697 |
| #37757 | 6:22 PM | ⚖️ | Test Suite Cleanup Plan Created Based on Audit Findings | ~640 |
**2026-01-05-fix-81-test-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37704 | 6:05 PM | ⚖️ | Plan Abandoned: Mock Logger Approach Rejected for Test Quality Audit | ~312 |
| #37699 | 5:59 PM | 🔵 | Test Failure Root Cause: Incomplete Logger Mocks Polluting Module Cache | ~455 |
**2026-01-05-github-issues-fix-plan.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37559 | 4:49 PM | 🔵 | GitHub Issues Fix Plan Loaded | ~428 |
*No recent activity*
</claude-mem-context>

View File

@@ -0,0 +1,262 @@
# CLAUDE.md Path Validation Bug Fix
## Problem Summary
Claude-Mem 9.0's distributed CLAUDE.md feature has a **critical path validation bug** that creates invalid directories when Claude SDK agent outputs non-path strings in file tracking XML tags (`<files_read>`, `<files_modified>`).
### Root Cause
In `src/utils/claude-md-utils.ts:234-239`:
```typescript
if (projectRoot && !path.isAbsolute(filePath)) {
absoluteFilePath = path.join(projectRoot, filePath);
}
```
- `path.isAbsolute('~/.claude-mem/logs')` returns `false` (Node.js doesn't recognize `~`)
- Code joins: `path.join(projectRoot, '~/.claude-mem/logs')``/project/~/.claude-mem/logs`
- `mkdirSync` creates literal directories
### Invalid Directories Currently in Repo
```
./~/ ← literal tilde directory
./PR #610 on thedotmack/ ← GitHub PR reference
./git diff for src/ ← git command text
./https:/code.claude.com/docs/en/ ← URL
```
---
## Implementation Plan
### Phase 1: Add Path Validation Function
**File:** `src/utils/claude-md-utils.ts`
Add new validation function after the imports (around line 16):
```typescript
/**
* Validate that a file path is safe for CLAUDE.md generation.
* Rejects tilde paths, URLs, command-like strings, and paths with invalid chars.
*
* @param filePath - The file path to validate
* @param projectRoot - Optional project root for boundary checking
* @returns true if path is valid for CLAUDE.md processing
*/
function isValidPathForClaudeMd(filePath: string, projectRoot?: string): boolean {
// Reject empty or whitespace-only
if (!filePath || !filePath.trim()) return false;
// Reject tilde paths (Node.js doesn't expand ~)
if (filePath.startsWith('~')) return false;
// Reject URLs
if (filePath.startsWith('http://') || filePath.startsWith('https://')) return false;
// Reject paths with spaces (likely command text or PR references)
if (filePath.includes(' ')) return false;
// Reject paths with # (GitHub issue/PR references)
if (filePath.includes('#')) return false;
// If projectRoot provided, ensure resolved path stays within project
if (projectRoot) {
const resolved = path.resolve(projectRoot, filePath);
const normalizedRoot = path.resolve(projectRoot);
if (!resolved.startsWith(normalizedRoot + path.sep) && resolved !== normalizedRoot) {
return false;
}
}
return true;
}
```
### Phase 2: Integrate Validation in updateFolderClaudeMdFiles
**File:** `src/utils/claude-md-utils.ts`
Modify the file path loop in `updateFolderClaudeMdFiles` (around line 232):
```typescript
for (const filePath of filePaths) {
if (!filePath || filePath === '') continue;
// VALIDATE PATH BEFORE PROCESSING
if (!isValidPathForClaudeMd(filePath, projectRoot)) {
logger.debug('FOLDER_INDEX', 'Skipping invalid file path', {
filePath,
reason: 'Failed path validation'
});
continue;
}
// ... rest of existing logic unchanged
}
```
### Phase 3: Add Unit Tests
**File:** `tests/utils/claude-md-utils.test.ts`
Add new test block after existing tests:
```typescript
describe('path validation in updateFolderClaudeMdFiles', () => {
it('should reject tilde paths', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['~/.claude-mem/logs/worker.log'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject URLs', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['https://example.com/file.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject paths with spaces', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['PR #610 on thedotmack/CLAUDE.md'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject paths with hash symbols', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['issue#123/file.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject path traversal outside project', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['../../../etc/passwd'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should accept valid relative paths', async () => {
const apiResponse = {
content: [{ text: '| #123 | 4:30 PM | 🔵 | Test | ~100 |' }]
};
const fetchMock = mock(() => Promise.resolve({
ok: true,
json: () => Promise.resolve(apiResponse)
} as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['src/utils/logger.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).toHaveBeenCalledTimes(1);
});
});
```
### Phase 4: Update .gitignore
**File:** `.gitignore`
Add at end of file:
```gitignore
# Prevent literal tilde directories (path validation bug artifacts)
~*/
# Prevent other malformed path directories
http*/
https*/
```
### Phase 5: Clean Up Invalid Directories
**Command sequence:**
```bash
rm -rf "~/."
rm -rf "PR #610 on thedotmack"
rm -rf "git diff for src"
rm -rf "https:"
```
### Phase 6: Verify and Commit
1. Run test suite: `npm test`
2. Run build: `npm run build`
3. Verify no invalid directories remain
4. Commit with message: `fix: Add path validation to CLAUDE.md distribution to prevent invalid directory creation`
---
## Files Modified
| File | Change |
|------|--------|
| `src/utils/claude-md-utils.ts` | Add `isValidPathForClaudeMd()` function + integrate in loop |
| `tests/utils/claude-md-utils.test.ts` | Add 6 new path validation tests |
| `.gitignore` | Add `~*/`, `http*/`, `https*/` patterns |
## Files Deleted
| Path | Reason |
|------|--------|
| `~/` (directory tree) | Invalid literal tilde directory |
| `PR #610 on thedotmack/` | Invalid PR reference directory |
| `git diff for src/` | Invalid git command directory |
| `https:/` | Invalid URL directory |
---
## Risk Assessment
**Low Risk:**
- Validation is additive (only skips invalid paths, doesn't change valid path handling)
- Existing tests remain unchanged
- Fire-and-forget design means failures are logged but don't break hooks
**Testing Coverage:**
- 6 new unit tests covering all rejection cases
- Existing 27 tests verify valid path behavior unchanged

View File

@@ -0,0 +1,144 @@
# Plan: Address PR #610 Review Issues
## Overview
This plan addresses the issues identified in the PR review for PR #610 "fix: Update hooks for Claude Code 2.1.0/1 - SessionStart no longer shows user messages".
## Phase 0: Verification and Discovery
### 0.1 Verify Test Failure
- **File**: `tests/hook-constants.test.ts`
- **Issue**: Lines 61-63 test for `HOOK_EXIT_CODES.USER_MESSAGE_ONLY` which was removed
- **Verification**: Run `bun test tests/hook-constants.test.ts` to confirm failure
### 0.2 Verify No Code References USER_MESSAGE_ONLY
- **Finding**: Grep found references only in:
- `tests/hook-constants.test.ts` (test file - needs fix)
- `src/services/CLAUDE.md` (memory context - auto-generated, not code)
- `plugin/scripts/CLAUDE.md` (memory context - auto-generated, not code)
- **Conclusion**: Only the test file needs updating; CLAUDE.md files are memory records
### 0.3 Verify CLAUDE.md Files Are Legitimate
- **Clarification**: The PR reviewer mentioned "user-specific CLAUDE.md files starting with ~/"
- **Finding**: All CLAUDE.md files in the commit are within the repository (`docs/`, `src/`, `plugin/`)
- **Conclusion**: These are legitimate in-repo context files, not user-specific paths
---
## Phase 1: Fix Test File (REQUIRED)
### Task 1.1: Remove USER_MESSAGE_ONLY Test
**File**: `tests/hook-constants.test.ts`
**Action**: Delete lines 61-63 that test for the removed constant
```typescript
// DELETE THESE LINES:
it('should define USER_MESSAGE_ONLY exit code', () => {
expect(HOOK_EXIT_CODES.USER_MESSAGE_ONLY).toBe(3);
});
```
### Task 1.2: Add Test for BLOCKING_ERROR
**File**: `tests/hook-constants.test.ts`
**Action**: Add test for the new `BLOCKING_ERROR` constant (exit code 2) that replaced it
```typescript
// ADD THIS TEST:
it('should define BLOCKING_ERROR exit code', () => {
expect(HOOK_EXIT_CODES.BLOCKING_ERROR).toBe(2);
});
```
### Verification
- Run `bun test tests/hook-constants.test.ts`
- Expect: All tests pass
---
## Phase 2: Documentation Consistency (NICE TO HAVE)
### Issue
Three similar notes about Claude Code 2.1.0 have slightly different wording:
1. `docs/public/architecture/hooks.mdx:254`:
> "SessionStart hooks no longer display any user-visible messages. Context is still injected via `hookSpecificOutput.additionalContext` but users don't see startup output in the UI."
2. `docs/public/hooks-architecture.mdx:31`:
> "SessionStart hooks no longer display any user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`."
3. `docs/public/hooks-architecture.mdx:441`:
> "SessionStart hooks output is never displayed to users. Context is injected silently via `hookSpecificOutput.additionalContext`."
### Task 2.1: Standardize Note Wording
**Action**: Use consistent wording across all three locations
**Standard text**:
```
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
```
### Files to Update
1. `docs/public/architecture/hooks.mdx:253-255` - Update Note block
2. `docs/public/hooks-architecture.mdx:30-32` - Update Note block
3. `docs/public/hooks-architecture.mdx:440-442` - Update Note block
### Verification
- Grep for the standard text in all three files
- Visual review of documentation
---
## Phase 3: Code Quality Improvements (OPTIONAL)
### Issue 3.1: Hardcoded Promotional Message
**File**: `src/hooks/context-hook.ts:66-68`
**Current code**:
```typescript
const enhancedContext = `${text}
Access 300k tokens of past research & decisions for just 19,008t. Use MCP search tools to access memories by ID.`;
```
### Options
1. **Leave as-is**: The token count is a rough estimate and doesn't need to be exact
2. **Make configurable**: Add to settings (over-engineering for this use case)
3. **Remove hardcoded numbers**: Use relative language instead
### Recommendation
Leave as-is for now. The token counts are marketing copy, not critical functionality. Creating a PR just for this adds unnecessary complexity.
---
## Phase 4: Final Verification
### 4.1 Run Full Test Suite
```bash
bun test
```
### 4.2 Build Verification
```bash
npm run build
```
### 4.3 Grep Verification
```bash
grep -r "USER_MESSAGE_ONLY" src/ --include="*.ts" --include="*.js"
```
Expected: No results (CLAUDE.md files excluded as they're memory records)
---
## Summary
| Phase | Priority | Effort | Description |
|-------|----------|--------|-------------|
| 1 | REQUIRED | 5 min | Fix test file - remove USER_MESSAGE_ONLY test, add BLOCKING_ERROR test |
| 2 | Nice to have | 10 min | Standardize documentation note wording |
| 3 | Skip | - | Hardcoded token counts are fine as-is |
| 4 | REQUIRED | 5 min | Run tests and build to verify |
## Expected Outcome
- All tests pass
- Build succeeds
- No code references to removed USER_MESSAGE_ONLY constant
- Documentation uses consistent wording (if Phase 2 is done)

9
.gitignore vendored
View File

@@ -23,4 +23,11 @@ src/ui/viewer.html
# Local MCP server config (for development only)
.mcp.json
.cursor/
.cursor/
# Prevent literal tilde directories (path validation bug artifacts)
~*/
# Prevent other malformed path directories
http*/
https*/

View File

@@ -91,18 +91,12 @@
|----|------|---|-------|------|
| #34238 | 10:31 PM | 🔄 | Rollback complete: simplified over-engineered concurrency and validation code | ~434 |
| #34231 | 10:25 PM | 🔴 | Fixed race conditions and security vulnerabilities in Cursor integration | ~562 |
| #34149 | 9:29 PM | 🟣 | Cross-Platform Cursor Hooks with Windows PowerShell Support | ~352 |
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34184 | 9:51 PM | 🔵 | Cursor Hooks Configuration Schema | ~375 |
**.gitignore**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34148 | 9:28 PM | 🟣 | Cursor IDE Integration with Cross-Platform Hooks and Documentation | ~514 |
### Dec 31, 2025
**session-init.sh**
@@ -126,4 +120,12 @@
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37990 | 9:00 PM | 🔵 | CLAUDE_MEM_WORKER_HOST setting used across 19 files | ~289 |
### Jan 7, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38195 | 7:35 PM | ✅ | Context-hook enhanced with promotional footer and user-message-hook removed from SessionStart | ~376 |
| #38194 | " | 🔵 | Working tree contains 10 modified files ready for commit | ~303 |
</claude-mem-context>

View File

@@ -3,32 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 29, 2025
**docs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34316 | 11:02 PM | 🔵 | Mintlify Documentation Structure Identified | ~242 |
### Jan 1, 2026
**SESSION_ID_ARCHITECTURE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35668 | 11:40 PM | ✅ | Main branch updated with major feature additions | ~377 |
| #35565 | 9:55 PM | ✅ | Session ID architecture documentation created | ~510 |
### Jan 3, 2026
**SESSION_ID_ARCHITECTURE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36689 | 11:56 PM | 🔵 | PR #538 Review Findings - Modular Architecture Refactor | ~590 |
| #36632 | 10:45 PM | 🔵 | SESSION_ID_ARCHITECTURE.md Documents Placeholder Pattern With ContentSessionId | ~584 |
| #36625 | 10:44 PM | 🔵 | Documentation and Code Reveal Placeholder Detection Pattern | ~583 |
**anti-pattern-cleanup-plan.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,111 +3,75 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Nov 13, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #7806 | 4:54 PM | 🔵 | PR #101 Enhancement: Continuation Prompt Token Reduction | ~634 |
### Nov 16, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #9976 | 11:35 PM | 🔵 | Endless Mode Architecture Plan Documented | ~661 |
| #9967 | 11:18 PM | ⚖️ | Endless Mode Architecture: Immutable Storage with Ephemeral Transform | ~217 |
### Nov 17, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #10131 | 1:22 AM | 🔵 | Endless Mode Token Economics Analysis Output: Complete Infrastructure Impact | ~542 |
| #10130 | " | ✅ | Integration of Actual Compute Savings Analysis into Main Execution Flow | ~258 |
| #10129 | " | 🔵 | Prompt Caching Economics: User Cost vs. Anthropic Compute Cost Divergence | ~451 |
| #10126 | 1:19 AM | 🔴 | Fix Return Statement Variable Names in playTheTapeThrough Function | ~313 |
| #10125 | " | ✅ | Redesign Timeline Display to Show Fresh/Cached Token Breakdown and Real Dollar Costs | ~501 |
| #10124 | " | ✅ | Replace Estimated Cost Model with Actual Caching-Based Costs in Anthropic Scale Analysis | ~516 |
| #10123 | " | ✅ | Pivot Session Length Comparison Table from Token to Cost Metrics | ~413 |
| #10122 | " | ✅ | Add Dual Reporting: Token Count vs Actual Cost in Comparison Output | ~410 |
| #10121 | 1:18 AM | ✅ | Apply Prompt Caching Cost Model to Endless Mode Calculation Function | ~501 |
| #10120 | " | ✅ | Integrate Prompt Caching Cost Calculations into Without-Endless-Mode Function | ~426 |
| #10119 | " | ✅ | Display Prompt Caching Pricing in Initial Calculator Output | ~297 |
| #10118 | " | ✅ | Add Prompt Caching Pricing Model to Token Economics Calculator | ~316 |
| #10115 | 1:15 AM | 🟣 | Token Economics Calculator for Endless Mode Sessions | ~465 |
| #10013 | 12:13 AM | 🔵 | Duplicate Agent SDK TypeScript Reference Documentation | ~340 |
| #10012 | " | 🔵 | Agent SDK TypeScript API Reference Complete | ~349 |
### Nov 18, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #11738 | 11:51 PM | ⚖️ | Comprehensive Architecture Document Created for Phase 1 | ~868 |
| #11711 | 11:44 PM | 🔵 | Language Model Tool Documentation Index | ~282 |
| #11710 | " | 🔵 | Language Model Tool API Implementation Guide | ~718 |
| #11709 | 11:43 PM | 🔵 | Comprehensive Copilot Extension Implementation Plan | ~624 |
| #11708 | " | 🔵 | VS Code Chat Sample Documentation Unavailable | ~327 |
| #11707 | " | 🔵 | VS Code Language Model API Structure and Capabilities | ~515 |
| #11705 | " | ⚖️ | VS Code Extension Development Planning Phase Initiated | ~327 |
| #11206 | 3:01 PM | 🔵 | mem-search skill architecture and migration details retrieved in full format | ~538 |
### Nov 25, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #15538 | 8:36 PM | 🔵 | Context Document for Landing Page Refinements | ~381 |
| #15314 | 5:04 PM | 🔵 | Endless Mode Documentation Post Retrieved with 156 Lines | ~671 |
### Dec 20, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31257 | 8:58 PM | ⚖️ | Eight Conflict Detection Hypotheses Evaluated with Simulation Results | ~525 |
| #31256 | " | 🔵 | Supersession vs Conflict Detection Feature Analysis | ~515 |
### Dec 30, 2025
**agent-sdk-v2-docs.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34477 | 2:25 PM | | V2 Upgrade Branch Modifies Four Files with Net Code Reduction | ~328 |
| #34466 | 2:24 PM | 🔵 | Agent SDK V2 Documentation Reveals Correct API Surface | ~399 |
| #34425 | 2:04 PM | 🔵 | Agent SDK V2 API Documentation and Migration Patterns | ~698 |
| #34422 | 2:03 PM | ✅ | Added Agent SDK V2 Documentation Files | ~240 |
| #34419 | 2:02 PM | ✅ | Committed Agent SDK V2 upgrade preparation | ~275 |
| #34520 | 2:34 PM | 🔵 | V2 Example Code Demonstrates All Key Patterns | ~537 |
### Jan 7, 2026
**agent-sdk-v2-example.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34431 | 2:06 PM | 🔵 | V2 SDK Executable Example Code Patterns | ~710 |
| #34428 | 2:05 PM | 🔵 | Agent SDK v2 Example File Reading Requested | ~204 |
| #34411 | 1:55 PM | ⚖️ | Agent SDK V2 Migration Plan Created | ~519 |
| #34410 | " | ⚖️ | Agent SDK V2 Migration Strategy Analysis | ~499 |
| #34406 | 1:54 PM | 🔵 | Comprehensive V2 Migration Analysis Shows Architectural Incompatibility | ~556 |
| #34401 | " | 🔵 | Agent SDK V2 API Design and Patterns | ~435 |
### Dec 31, 2025
**agent-sdk-v2-preview.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34635 | 3:04 PM | 🟣 | Documentation-First Workflow Design Document Created | ~769 |
| #34616 | 2:59 PM | ⚖️ | Documentation-First Workflow Agent Analyzing V2 SDK Examples and Patterns | ~515 |
| #34581 | 2:44 PM | 🔵 | V2 Session API Official Documentation Confirms Clear Separation Pattern | ~446 |
**agent-sdk-v2-examples.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34605 | 2:57 PM | 🔵 | V2 SDK Migration Failure Root Cause: Context Rot and Knowledge Transfer Gaps | ~550 |
| #34583 | 2:44 PM | 🔵 | Executable V2 Examples Demonstrate All Core Patterns With Crystal Clear Code | ~471 |
| #34580 | 2:43 PM | 🔵 | V2 Session API Documentation Shows Clear Send/Receive Pattern Despite Naming Confusion | ~364 |
### Jan 1, 2026
**try-catch-audit-report.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35635 | 11:14 PM | ✅ | Removed Temporary Try-Catch Audit Report | ~224 |
| #35463 | 8:59 PM | 🟣 | Enforceable Anti-Pattern Detection System for Try-Catch Abuse | ~485 |
| #35462 | " | 🟣 | Error handling audit tooling and documentation added | ~271 |
| #35435 | 8:46 PM | ✅ | Try-Catch Audit Report Documented in Markdown | ~781 |
**agent-sdk-v2-examples.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35429 | 6:32 PM | ⚖️ | KISS Principle Applied to SDKAgent.ts Defensive Code | ~322 |
| #35412 | 5:25 PM | 🔵 | Canonical Example Shows Cost Tracking Without Token Usage Checks | ~289 |
| #35406 | 5:24 PM | ⚖️ | Categorized Conditionals as Required Business Logic vs Defensive Code | ~377 |
| #35404 | " | 🔵 | Canonical V2 SDK Patterns Require Message Type Checking | ~313 |
| #35398 | 5:23 PM | 🟣 | Added comprehensive Claude Agent SDK V2 examples | ~231 |
| #35383 | 3:11 PM | 🔵 | Phase 2 code quality review identified 5 critical bugs | ~604 |
| #35382 | 3:08 PM | ✅ | Phase 2 Anti-Pattern Recheck Passed | ~315 |
| #35379 | 3:07 PM | 🔵 | Phase 2 Anti-Pattern Check Found Content Extraction Bug | ~373 |
| #35353 | 3:01 PM | 🔵 | Phase 2 preparation analysis completed | ~502 |
| #35340 | 2:58 PM | 🔵 | Phase 1 Anti-Pattern Check Reveals V1/V2 API Mismatch | ~352 |
| #35330 | 2:54 PM | 🔵 | Claude Agent SDK V2 API Pattern Documentation | ~305 |
| #35329 | 2:53 PM | 🔵 | Agent SDK V2 API patterns and capabilities | ~453 |
| #35292 | 1:23 PM | 🔵 | Agent SDK query() resume parameter: SDK-generated session IDs cannot be predetermined | ~543 |
**sdkagent-removal-list.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35425 | 5:27 PM | ✅ | Reorganized Removal List with DELETE/SIMPLIFY Section Header | ~240 |
| #35424 | " | ✅ | Revised Token Tracking from Delete to Simplify with Hardcoded Zero | ~365 |
| #35416 | 5:25 PM | 🟣 | Created Actionable Removal Checklist for SDKAgent.ts Cleanup | ~431 |
**agent-sdk-v2-preview.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35414 | 5:25 PM | 🔵 | V2 Preview Documentation Shows Direct Result Access Pattern | ~281 |
| #35289 | 1:23 PM | 🔵 | Agent SDK V2 preview documentation: Explicit session lifecycle with createSession and resumeSession | ~523 |
**sdkagent-conditional-logic-CORRECTED.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35409 | 5:24 PM | 🟣 | Created Comprehensive Conditional Logic Removal Report | ~488 |
**dont-be-an-idiot.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35400 | 5:23 PM | 🔄 | Phase 1 SDK V2 migration - Updated imports and added API documentation | ~294 |
| #35347 | 3:01 PM | ✅ | Phase 1 commit completed via Task agent | ~374 |
| #35346 | " | ✅ | Committed Phase 1 of V2 API migration | ~333 |
| #35345 | 3:00 PM | ✅ | Phase 1 Changes Committed to Git | ~338 |
| #35343 | " | ✅ | Phase 1 Git Status Shows Modified Files | ~315 |
| #35334 | 2:55 PM | 🔵 | V2 SDK Migration Preparation Complete | ~368 |
| #35332 | 2:54 PM | 🟣 | SDK V2 API Documentation Created | ~305 |
| #35331 | " | ✅ | Created documentation affirming V2 API stability | ~358 |
### Jan 2, 2026
**try-catch-audit-report.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35703 | 1:01 PM | ⚖️ | Try-Catch as Anti-Pattern: Root Cause Analysis and Documentation | ~363 |
### Jan 6, 2026
**windows-code-evaluation.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
| #38209 | 7:39 PM | 🔵 | Claude Code Hooks System Architecture and Usage | ~491 |
</claude-mem-context>

View File

@@ -0,0 +1,338 @@
# Get started with Claude Code hooks
> Learn how to customize and extend Claude Code's behavior by registering shell commands
Claude Code hooks are user-defined shell commands that execute at various points
in Claude Code's lifecycle. Hooks provide deterministic control over Claude
Code's behavior, ensuring certain actions always happen rather than relying on
the LLM to choose to run them.
<Tip>
For reference documentation on hooks, see [Hooks reference](/en/hooks).
</Tip>
Example use cases for hooks include:
* **Notifications**: Customize how you get notified when Claude Code is awaiting
your input or permission to run something.
* **Automatic formatting**: Run `prettier` on .ts files, `gofmt` on .go files,
etc. after every file edit.
* **Logging**: Track and count all executed commands for compliance or
debugging.
* **Feedback**: Provide automated feedback when Claude Code produces code that
does not follow your codebase conventions.
* **Custom permissions**: Block modifications to production files or sensitive
directories.
By encoding these rules as hooks rather than prompting instructions, you turn
suggestions into app-level code that executes every time it is expected to run.
<Warning>
You must consider the security implication of hooks as you add them, because hooks run automatically during the agent loop with your current environment's credentials.
For example, malicious hooks code can exfiltrate your data. Always review your hooks implementation before registering them.
For full security best practices, see [Security Considerations](/en/hooks#security-considerations) in the hooks reference documentation.
</Warning>
## Hook Events Overview
Claude Code provides several hook events that run at different points in the
workflow:
* **PreToolUse**: Runs before tool calls (can block them)
* **PermissionRequest**: Runs when a permission dialog is shown (can allow or deny)
* **PostToolUse**: Runs after tool calls complete
* **UserPromptSubmit**: Runs when the user submits a prompt, before Claude processes it
* **Notification**: Runs when Claude Code sends notifications
* **Stop**: Runs when Claude Code finishes responding
* **SubagentStop**: Runs when subagent tasks complete
* **PreCompact**: Runs before Claude Code is about to run a compact operation
* **SessionStart**: Runs when Claude Code starts a new session or resumes an existing session
* **SessionEnd**: Runs when Claude Code session ends
Each event receives different data and can control Claude's behavior in
different ways.
## Quickstart
In this quickstart, you'll add a hook that logs the shell commands that Claude
Code runs.
### Prerequisites
Install `jq` for JSON processing in the command line.
### Step 1: Open hooks configuration
Run the `/hooks` [slash command](/en/slash-commands) and select
the `PreToolUse` hook event.
`PreToolUse` hooks run before tool calls and can block them while providing
Claude feedback on what to do differently.
### Step 2: Add a matcher
Select `+ Add new matcher…` to run your hook only on Bash tool calls.
Type `Bash` for the matcher.
<Note>You can use `*` to match all tools.</Note>
### Step 3: Add the hook
Select `+ Add new hook…` and enter this command:
```bash theme={null}
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt
```
### Step 4: Save your configuration
For storage location, select `User settings` since you're logging to your home
directory. This hook will then apply to all projects, not just your current
project.
Then press `Esc` until you return to the REPL. Your hook is now registered.
### Step 5: Verify your hook
Run `/hooks` again or check `~/.claude/settings.json` to see your configuration:
```json theme={null}
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
}
]
}
]
}
}
```
### Step 6: Test your hook
Ask Claude to run a simple command like `ls` and check your log file:
```bash theme={null}
cat ~/.claude/bash-command-log.txt
```
You should see entries like:
```
ls - Lists files and directories
```
## More Examples
<Note>
For a complete example implementation, see the [bash command validator example](https://github.com/anthropics/claude-code/blob/main/examples/hooks/bash_command_validator_example.py) in our public codebase.
</Note>
### Code Formatting Hook
Automatically format TypeScript files after editing:
```json theme={null}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }"
}
]
}
]
}
}
```
### Markdown Formatting Hook
Automatically fix missing language tags and formatting issues in markdown files:
```json theme={null}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/markdown_formatter.py"
}
]
}
]
}
}
```
Create `.claude/hooks/markdown_formatter.py` with this content:
````python theme={null}
#!/usr/bin/env python3
"""
Markdown formatter for Claude Code output.
Fixes missing language tags and spacing issues while preserving code content.
"""
import json
import sys
import re
import os
def detect_language(code):
"""Best-effort language detection from code content."""
s = code.strip()
# JSON detection
if re.search(r'^\s*[{\[]', s):
try:
json.loads(s)
return 'json'
except:
pass
# Python detection
if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
re.search(r'^\s*(import|from)\s+\w+', s, re.M):
return 'python'
# JavaScript detection
if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
re.search(r'=>|console\.(log|error)', s):
return 'javascript'
# Bash detection
if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
return 'bash'
# SQL detection
if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
return 'sql'
return 'text'
def format_markdown(content):
"""Format markdown content with language detection."""
# Fix unlabeled code fences
def add_lang_to_fence(match):
indent, info, body, closing = match.groups()
if not info.strip():
lang = detect_language(body)
return f"{indent}```{lang}\n{body}{closing}\n"
return match.group(0)
fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
content = re.sub(fence_pattern, add_lang_to_fence, content)
# Fix excessive blank lines (only outside code fences)
content = re.sub(r'\n{3,}', '\n\n', content)
return content.rstrip() + '\n'
# Main execution
try:
input_data = json.load(sys.stdin)
file_path = input_data.get('tool_input', {}).get('file_path', '')
if not file_path.endswith(('.md', '.mdx')):
sys.exit(0) # Not a markdown file
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
formatted = format_markdown(content)
if formatted != content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(formatted)
print(f"✓ Fixed markdown formatting in {file_path}")
except Exception as e:
print(f"Error formatting markdown: {e}", file=sys.stderr)
sys.exit(1)
````
Make the script executable:
```bash theme={null}
chmod +x .claude/hooks/markdown_formatter.py
```
This hook automatically:
* Detects programming languages in unlabeled code blocks
* Adds appropriate language tags for syntax highlighting
* Fixes excessive blank lines while preserving code content
* Only processes markdown files (`.md`, `.mdx`)
### Custom Notification Hook
Get desktop notifications when Claude needs input:
```json theme={null}
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' 'Awaiting your input'"
}
]
}
]
}
}
```
### File Protection Hook
Block edits to sensitive files:
```json theme={null}
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 -c \"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\""
}
]
}
]
}
}
```
## Learn more
* For reference documentation on hooks, see [Hooks reference](/en/hooks).
* For comprehensive security best practices and safety guidelines, see [Security Considerations](/en/hooks#security-considerations) in the hooks reference documentation.
* For troubleshooting steps and debugging techniques, see [Debugging](/en/hooks#debugging) in the hooks reference
documentation.
---
> To find navigation and other pages in this documentation, fetch the llms.txt file at: https://code.claude.com/docs/llms.txt

View File

@@ -93,165 +93,84 @@ npx mintlify dev
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 28, 2025
### Nov 18, 2025
**platform-integration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33540 | 10:55 PM | 🔵 | Grep search found mem-search references in internationalized documentation | ~577 |
| #33522 | 10:46 PM | 🔵 | Platform integration documentation describes Worker API architecture | ~351 |
| #11206 | 3:01 PM | 🔵 | mem-search skill architecture and migration details retrieved in full format | ~538 |
### Nov 21, 2025
**docs.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33312 | 3:09 PM | | OpenRouter Provider Documentation | ~497 |
| #13221 | 2:01 AM | 🔴 | Fixed broken markdown link to Viewer UI documentation | ~316 |
| #13220 | 2:00 AM | 🔴 | Escaped HTML less-than symbol in universal architecture timeout documentation | ~316 |
| #13216 | 1:54 AM | ✅ | Universal Architecture Added to Navigation | ~330 |
| #13215 | " | 🟣 | Universal AI Memory Architecture Documentation Created | ~732 |
| #13213 | 1:50 AM | 🔵 | Introduction Page Content and Recent v6.0.0 Release | ~495 |
| #13212 | " | 🔵 | Architecture Evolution Documentation Structure | ~408 |
| #13211 | " | 🔵 | Mintlify Documentation Site Configuration | ~430 |
| #13209 | 1:48 AM | 🔵 | Public Documentation Structure and Guidelines | ~383 |
### Nov 25, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #14994 | 2:22 PM | ✅ | Version Channel Section Added to Configuration Documentation | ~301 |
| #14993 | " | ✅ | Beta Features Added to Documentation Navigation | ~188 |
| #14992 | 2:21 PM | 🟣 | Beta Features Documentation Page Created | ~488 |
| #14991 | " | 🔵 | Mintlify Navigation Structure and Documentation Groups | ~394 |
| #14989 | " | 🔵 | Installation Documentation with Quick Start and Verification Steps | ~383 |
| #14988 | " | 🔵 | Configuration Documentation Structure and Environment Variables | ~338 |
### Nov 26, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #16190 | 10:22 PM | 🔵 | RAGTIME Search Retrieved Five Observations About Claude-Mem vs RAG Architecture | ~637 |
### Dec 3, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #19884 | 9:42 PM | 🔵 | Configuration system and environment variables | ~701 |
| #19878 | 9:40 PM | 🔵 | Installation process and system architecture | ~486 |
### Dec 8, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #22335 | 10:26 PM | 🔵 | Mintlify documentation configuration analyzed | ~534 |
| #22311 | 9:47 PM | 🔵 | Comprehensive Hooks Architecture Documentation Review | ~263 |
| #22297 | 9:43 PM | 🔵 | Mintlify Documentation Framework Configuration | ~446 |
| #22294 | " | 🔵 | Documentation Site Structure Located | ~359 |
### Dec 9, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23179 | 10:44 PM | ✅ | Removed explanatory reasons from tool exclusion documentation | ~297 |
### Dec 15, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27038 | 6:02 PM | 🔵 | 95% token reduction claims found only in private experimental documents, not in main public docs | ~513 |
| #27037 | " | 🔵 | Branch switching functionality exists in SettingsRoutes with UI switcher removal intent | ~463 |
| #26986 | 5:24 PM | ✅ | Updated Endless Mode latency warning in beta features documentation | ~299 |
### Dec 29, 2025
**docs.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34321 | 11:03 PM | 🔵 | Mintlify Navigation Configuration Defines Expected File Paths | ~330 |
| #34215 | 10:08 PM | 🔵 | Retrieved Detailed Cursor Integration Implementation History | ~676 |
| #34148 | 9:28 PM | 🟣 | Cursor IDE Integration with Cross-Platform Hooks and Documentation | ~514 |
| #34112 | 9:07 PM | 🟣 | Committed Cursor Public Documentation to Repository | ~427 |
| #34108 | 9:06 PM | 🟣 | Added Cursor Integration Section to Documentation Navigation | ~441 |
| #34101 | 9:04 PM | 🔵 | Documentation Navigation Configuration Using Mintlify | ~445 |
| #33938 | 6:27 PM | 🔵 | Relevant CLAUDE.md Context Identified for PR #492 | ~435 |
| #33750 | 12:25 AM | | Documentation Update: Removed Version Number from Architecture Evolution | ~281 |
### Jan 7, 2026
**public**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34318 | 11:03 PM | 🔵 | Mintlify Documentation Files and Configuration Located | ~294 |
**installation.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34102 | 9:04 PM | 🔵 | Current Installation Documentation Targets Claude Code Plugin Users | ~485 |
**progressive-disclosure.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33773 | 12:38 AM | ✅ | Replaced two-tier with three-layer workflow documentation | ~431 |
| #33772 | " | ✅ | Updated progressive disclosure docs with 3-layer MCP workflow | ~399 |
| #33771 | 12:37 AM | 🔵 | Progressive disclosure design rationale documented | ~508 |
| #33770 | " | 🔵 | Progressive disclosure documentation reviewed | ~479 |
| #33715 | 12:18 AM | ✅ | Future enhancements section updated for current API structure | ~308 |
| #33712 | " | ✅ | Progressive disclosure docs updated to reflect 3-layer workflow | ~363 |
| #33702 | 12:09 AM | ⚖️ | Documentation Update Strategy Finalized for MCP Architecture Transition | ~845 |
| #33696 | 12:07 AM | 🔵 | Progressive Disclosure Philosophy Requires Tool Name Updates | ~687 |
| #33685 | 12:04 AM | 🔵 | Progressive Disclosure Philosophy Document References Deprecated Tools | ~543 |
**architecture-evolution.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33763 | 12:27 AM | ✅ | Pull request #480 created for MCP architecture documentation updates | ~423 |
| #33760 | 12:26 AM | ✅ | Major documentation overhaul across 6 files with 908 additions | ~367 |
| #33749 | 12:25 AM | ✅ | Documentation Version Reference Removed | ~282 |
| #33747 | " | ✅ | Removed specific version reference from MCP architecture section | ~279 |
| #33745 | " | ✅ | Documentation Version Reference Simplified | ~224 |
| #33744 | " | ✅ | Removed fabricated version number from architecture documentation | ~319 |
| #33726 | 12:20 AM | 🟣 | v6.5.0 architecture evolution documentation added | ~599 |
| #33700 | 12:08 AM | 🔵 | Architecture Evolution Document Contains Historical MCP Tool References | ~625 |
**troubleshooting.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33722 | 12:19 AM | ✅ | Token limit troubleshooting completely rewritten for 3-layer workflow | ~426 |
| #33720 | " | ✅ | Troubleshooting search query examples updated to current API | ~329 |
| #33717 | " | 🔵 | Troubleshooting docs contain outdated search_observations references | ~333 |
| #33693 | 12:06 AM | 🔵 | Troubleshooting Documentation Contains Deprecated Search Tool Syntax | ~576 |
**introduction.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33687 | 12:05 AM | 🔵 | Introduction Documentation References mem-search Skill | ~426 |
### Dec 31, 2025
**troubleshooting.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34688 | 3:40 PM | 🔵 | Worker Logs Command Usage Across Codebase | ~320 |
### Jan 1, 2026
**context-engineering.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35459 | 8:57 PM | 🔵 | Existing Coding Standards and Anti-Pattern References in Codebase | ~600 |
### Jan 2, 2026
**architecture-evolution.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36096 | 10:23 PM | 🔵 | Observation API Function Names Located | ~227 |
### Jan 3, 2026
**architecture-evolution.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36353 | 8:42 PM | 🔵 | Multiple observation table definitions found across codebase | ~280 |
### Jan 4, 2026
**hooks-architecture.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36941 | 2:43 AM | 🔵 | Context Injection Header Format | ~220 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38082 | 10:13 PM | ✅ | Merge Conflict Resolution - Kept Feature Branch Versions | ~431 |
**progressive-disclosure.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38069 | 9:51 PM | 🔵 | Progressive Disclosure Philosophy Documentation | ~546 |
**docs.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38066 | 9:50 PM | ✅ | v9.0 Documentation Audit Completed with 14 Files Updated | ~547 |
| #38064 | " | ⚖️ | 9.0 Release Documentation Audit Complete - Major Gaps Identified | ~997 |
| #38035 | 9:42 PM | 🔵 | Documentation Navigation Structure for 9.0 Release | ~422 |
**modes.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38060 | 9:49 PM | 🔵 | Modes System Documentation for Workflow and Language Configuration | ~514 |
**configuration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38054 | 9:47 PM | 🔵 | Configuration Documentation Review - Missing Live Context Settings | ~530 |
**platform-integration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38052 | 9:46 PM | 🔵 | Platform Integration Documentation Review | ~525 |
**hooks-architecture.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38045 | 9:45 PM | 🔵 | Hooks Architecture Documentation Review | ~520 |
**introduction.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38044 | 9:44 PM | 🔵 | Introduction Documentation Review for 9.0 Release | ~462 |
**context-engineering.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38043 | 9:44 PM | 🔵 | Context Engineering Documentation Review | ~455 |
**troubleshooting.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37548 | 4:48 PM | ✅ | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
| #38233 | 7:42 PM | | Renumbered SessionEnd Hook from 6 to 5 | ~315 |
| #38229 | 7:41 PM | ✅ | Renumbered PostToolUse Hook from 4 to 3 | ~278 |
| #38225 | " | ✅ | Updated Hook Count Description in Hooks Architecture Documentation | ~352 |
</claude-mem-context>

View File

@@ -3,147 +3,36 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 16, 2025
### Nov 18, 2025
**worker-service.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28299 | 9:57 PM | | Documentation Updated for Renamed MCP Tools | ~305 |
| #28293 | 9:56 PM | 🔵 | get_batch_observations Usage Across Codebase | ~226 |
| #28292 | " | 🔵 | get_batch_observations Referenced in 4 Files | ~246 |
| #28242 | 9:38 PM | 🔵 | Progressive Description and Batch Observations Usage Sites | ~241 |
| #11206 | 3:01 PM | 🔵 | mem-search skill architecture and migration details retrieved in full format | ~538 |
### Nov 21, 2025
**search-architecture.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28074 | 8:09 PM | 🔵 | Progressive Disclosure Pattern and Search Implementation | ~558 |
| #28067 | " | 🔵 | Progressive Disclosure and Security Architecture | ~528 |
| #28066 | 8:08 PM | 🔵 | Search Architecture Evolution from MCP to Skill-Based | ~530 |
| #28058 | " | 🔵 | Search Architecture Evolution from MCP Tools to Skill-Based HTTP API | ~528 |
| #13218 | 1:58 AM | 🔴 | Escaped HTML special character in MDX documentation | ~261 |
### Dec 3, 2025
**pm2-to-bun-migration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27716 | 5:41 PM | | Better-sqlite3 References Removed from Codebase | ~319 |
| #27715 | " | 🔵 | Git Branch Already Created | ~208 |
| #27712 | 5:40 PM | 🟣 | Merged PR #332: API-Based Import/Export Architecture | ~372 |
| #27699 | 5:37 PM | 🔵 | Comprehensive PM2 to Bun migration documentation exists | ~360 |
| #27696 | 5:36 PM | 🔵 | Documentation already reflects better-sqlite3 to bun:sqlite migration | ~390 |
| #27695 | " | 🔵 | Better-sqlite3 references found in documentation | ~201 |
| #27687 | 5:32 PM | 🔴 | Corrected Migration Date in PM2 to Bun Documentation | ~270 |
| #27656 | 5:24 PM | ⚖️ | PM2 to Bun Documentation Migration Plan Created | ~551 |
| #27655 | " | 🟣 | PM2 to Bun Documentation Migration Plan Created | ~455 |
| #27654 | 5:22 PM | 🔵 | Complete PM2 Documentation Audit | ~458 |
| #19891 | 9:43 PM | 🔵 | Seven hook scripts across five lifecycle events | ~713 |
### Dec 17, 2025
### Dec 15, 2025
**pm2-to-bun-migration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28930 | 7:30 PM | 🔵 | Worker CLI Distribution and Build System | ~275 |
| #27040 | 6:03 PM | 🔵 | Comprehensive search confirms no 95% claims exist in main branch public documentation | ~508 |
| #27037 | 6:02 PM | 🔵 | Branch switching functionality exists in SettingsRoutes with UI switcher removal intent | ~463 |
### Jan 7, 2026
**worker-service.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28929 | 7:30 PM | 🔵 | ProcessManager Usage Across Codebase | ~319 |
### Dec 18, 2025
**database.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29815 | 7:33 PM | 🔵 | Database contains multiple session table schemas | ~311 |
### Dec 20, 2025
**worker-service.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30675 | 5:08 PM | 🔵 | Platform Documentation Across 18 Files | ~335 |
**overview.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30253 | 3:17 PM | 🔵 | Agent SDK Integration Throughout Codebase | ~402 |
### Dec 24, 2025
**hooks.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32193 | 7:42 PM | 🔵 | Session completion endpoint usage across codebase | ~278 |
### Dec 25, 2025
**worker-service.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32654 | 8:51 PM | 🔵 | Identified multiple files related to queue recovery | ~375 |
| #32456 | 5:41 PM | ✅ | Completed merge of main branch into feature/titans-phase1-3 | ~354 |
| #32432 | 3:41 PM | 🟣 | Manual Queue Recovery System with CLI and API | ~531 |
| #32425 | 3:26 PM | ✅ | API Documentation for Manual Recovery Endpoints Added | ~563 |
### Dec 27, 2025
**hooks.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33101 | 7:11 PM | 🔵 | Context Injection API Endpoint Usage Across Hooks | ~358 |
### Dec 28, 2025
**search-architecture.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33540 | 10:55 PM | 🔵 | Grep search found mem-search references in internationalized documentation | ~577 |
### Dec 29, 2025
**search-architecture.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33769 | 12:37 AM | ✅ | Documentation updated for MCP-based search architecture | ~528 |
| #33767 | 12:34 AM | ✅ | Committed MDX Syntax Fix to updates/docs Branch | ~301 |
| #33766 | " | 🔴 | Fixed MDX Syntax Error in Performance Section | ~293 |
| #33765 | 12:33 AM | 🔵 | Search Architecture Documentation Structure Analysis | ~524 |
| #33763 | 12:27 AM | ✅ | Pull request #480 created for MCP architecture documentation updates | ~423 |
| #33762 | " | ✅ | Architecture shift from skill-based to MCP-based search with 3-layer workflow | ~418 |
| #33760 | 12:26 AM | ✅ | Major documentation overhaul across 6 files with 908 additions | ~367 |
| #33756 | 12:25 AM | ✅ | Documentation Version Reference Removed from Search Architecture | ~257 |
| #33754 | " | ✅ | Removed fabricated version range from skill-based approach comparison | ~318 |
| #33753 | " | ✅ | Documentation Version Number Removed from Architecture Evolution Section | ~233 |
| #33751 | " | 🔵 | Architecture Evolution Documentation Records v6.5.0 Migration | ~227 |
| #33702 | 12:09 AM | ⚖️ | Documentation Update Strategy Finalized for MCP Architecture Transition | ~845 |
| #33698 | 12:07 AM | 🔵 | Search Architecture Documentation Comprehensively Describes Deleted Skill System | ~663 |
| #33680 | 12:03 AM | 🔵 | Search Architecture Documentation Describes Deleted Skill System | ~576 |
### Dec 31, 2025
**pm2-to-bun-migration.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34688 | 3:40 PM | 🔵 | Worker Logs Command Usage Across Codebase | ~320 |
### Jan 2, 2026
**database.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36096 | 10:23 PM | 🔵 | Observation API Function Names Located | ~227 |
### Jan 3, 2026
**database.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36353 | 8:42 PM | 🔵 | Multiple observation table definitions found across codebase | ~280 |
### Jan 5, 2026
**overview.mdx**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38066 | 9:50 PM | ✅ | v9.0 Documentation Audit Completed with 14 Files Updated | ~547 |
| #38064 | " | ⚖️ | 9.0 Release Documentation Audit Complete - Major Gaps Identified | ~997 |
| #38059 | 9:49 PM | 🔵 | Architecture Overview Documentation Review | ~554 |
| #38221 | 7:41 PM | | Removed User Message Hook Documentation Section | ~339 |
| #38218 | 7:40 PM | ✅ | Updated Hook Configuration Documentation to Match Implementation | ~382 |
| #38212 | " | 🔵 | 5-Stage Hook Lifecycle Architecture for Memory Agent | ~668 |
</claude-mem-context>

View File

@@ -177,7 +177,7 @@ graph TB
| Stage | Hook | Trigger | Purpose |
|-------|------|---------|---------|
| **1. SessionStart** | `context-hook.js` + `user-message-hook.js` | User opens Claude Code | Inject prior context, show UI messages |
| **1. SessionStart** | `context-hook.js` | User opens Claude Code | Inject prior context silently |
| **2. UserPromptSubmit** | `new-hook.js` | User submits a prompt | Create/get session, save prompt, init worker |
| **3. PostToolUse** | `save-hook.js` | Claude uses any tool | Queue observation for AI compression |
| **4. Stop** | `summary-hook.js` | User stops asking questions | Generate session summary |
@@ -194,12 +194,16 @@ Hooks are configured in `plugin/hooks/hooks.json`:
"matcher": "startup|clear|compact",
"hooks": [{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/smart-install.js",
"timeout": 300
}, {
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js",
"timeout": 10
"command": "bun ${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs start",
"timeout": 60
}, {
"type": "command",
"command": "bun ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
"timeout": 60
}]
}],
"UserPromptSubmit": [{
@@ -242,8 +246,13 @@ Hooks are configured in `plugin/hooks/hooks.json`:
**Timing**: When user opens Claude Code or resumes session
**Hooks Triggered** (in order):
1. `context-hook.js` - Fetches and injects prior session context
2. `user-message-hook.js` - Displays context info to user via stderr
1. `smart-install.js` - Ensures dependencies are installed
2. `worker-service.cjs start` - Starts the worker service
3. `context-hook.js` - Fetches and silently injects prior session context
<Note>
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
</Note>
### Sequence Diagram
@@ -306,19 +315,6 @@ sequenceDiagram
**Implementation**: `src/hooks/context-hook.ts`
### User Message Hook (`user-message-hook.js`)
**Purpose**: Display helpful user messages during first-time setup or when viewing context.
**Behavior**:
- Shows first-time setup message when `node_modules` is missing
- Displays formatted context information with colors
- Provides tips for using claude-mem effectively
- Shows link to viewer UI (`http://localhost:37777`)
- Uses stderr as communication channel (only output available in Claude Code UI)
**Implementation**: `src/hooks/user-message-hook.ts`
---
## Stage 2: UserPromptSubmit

View File

@@ -22,11 +22,15 @@ Claude-Mem is fundamentally a **hook-driven system**. Every piece of functionali
┌─────────────────────────────────────────────────────────┐
│ CLAUDE-MEM SYSTEM │
│ │
│ Smart Context User New Obs │
│ Install Inject Message Session Capture │
│ Smart Worker Context New Obs │
│ Install Start Inject Session Capture │
└─────────────────────────────────────────────────────────┘
```
<Note>
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
</Note>
**Key insight:** Claude-Mem doesn't interrupt or modify Claude Code's behavior. It observes from the outside and provides value through lifecycle hooks.
---
@@ -68,9 +72,9 @@ Claude Code's hook system provides exactly what we need:
---
## The Six Hook Scripts + Pre-Hook
## The Hook Scripts
Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-hook script for dependency management. SessionStart runs 2 hooks in sequence (after the pre-hook script).
Claude-Mem uses lifecycle hook scripts across 5 lifecycle events. SessionStart runs 3 hooks in sequence: smart-install, worker-service start, and context-hook.
### Pre-Hook: Smart Install (Before SessionStart)
@@ -155,56 +159,7 @@ Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-h
---
### Hook 2: SessionStart - User Message
**Purpose:** Display helpful user messages during first-time setup
**When:** Claude Code starts (runs after context-hook)
**What it does:**
1. Checks if dependencies are installed
2. Shows first-time setup message if needed
3. Displays formatted context information with colors
4. Shows link to viewer UI (http://localhost:37777)
5. Exits with code 3 (informational, not error)
**Configuration:**
```json
{
"hooks": {
"SessionStart": [{
"matcher": "startup|clear|compact",
"hooks": [{
"type": "command",
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js",
"timeout": 10
}]
}]
}
}
```
**Output Example:**
```
📝 Claude-Mem Context Loaded
Note: This appears as stderr but is informational only
[Context details with colors...]
📺 Watch live in browser http://localhost:37777/ (New! v5.1)
```
**Key Features:**
- ✅ User-friendly first-time experience
- ✅ Visual context display
- ✅ Links to viewer UI
- ✅ Non-intrusive (exit code 3)
**Source:** `plugin/scripts/user-message-hook.js` (minified)
---
### Hook 3: UserPromptSubmit (New Session Hook)
### Hook 2: UserPromptSubmit (New Session Hook)
**Purpose:** Initialize session tracking when user submits a prompt
@@ -251,7 +206,7 @@ VALUES (?, ?, ?, ...)
---
### Hook 4: PostToolUse (Save Observation Hook)
### Hook 3: PostToolUse (Save Observation Hook)
**Purpose:** Capture tool execution observations for later processing
@@ -312,7 +267,7 @@ VALUES (?, ?, ?, ?, ...)
---
### Hook 5: Stop Hook (Summary Generation)
### Hook 4: Stop Hook (Summary Generation)
**Purpose:** Generate AI-powered session summaries during the session
@@ -367,7 +322,7 @@ VALUES (?, ?, ?, ?, ...)
---
### Hook 6: SessionEnd (Cleanup Hook)
### Hook 5: SessionEnd (Cleanup Hook)
**Purpose:** Mark sessions as completed when they end
@@ -474,14 +429,18 @@ sequenceDiagram
| Event | Timing | Blocking | Timeout | Output Handling |
|-------|--------|----------|---------|-----------------|
| **SessionStart (smart-install)** | Before session | No | 300s | stderr (info) |
| **SessionStart (context)** | Before session | No | 300s | stdout → context |
| **SessionStart (user-message)** | Before session | No | 10s | stderr (info) |
| **UserPromptSubmit** | Before processing | No | 120s | stdout → context |
| **SessionStart (smart-install)** | Before session | No | 300s | stderr (log only) |
| **SessionStart (worker-start)** | Before session | No | 60s | stderr (log only) |
| **SessionStart (context)** | Before session | No | 60s | JSON → additionalContext (silent) |
| **UserPromptSubmit** | Before processing | No | 60s | stdout → context |
| **PostToolUse** | After tool | No | 120s | Transcript only |
| **Summary** | Worker triggered | No | 120s | Database |
| **SessionEnd** | On exit | No | 120s | Log only |
<Note>
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
</Note>
---
## The Worker Service Architecture

View File

@@ -0,0 +1,144 @@
# All Open Issues Explained
*Generated: January 7, 2026*
This report provides plain English explanations of all 12 open GitHub issues, their root causes, and proposed solutions.
---
## Critical Priority (P0)
### #603 - Memory Leak from Child Processes
When you use claude-mem on Linux/Mac, it spawns helper processes to analyze your work. These processes never get cleaned up when they're done - they just sit there eating RAM. One user had 121 zombie processes using 44GB of memory after 6 hours.
**Root cause:** The `getChildProcesses()` function in ProcessManager.ts only works on Windows (using WMIC). On Linux/Mac, it returns an empty array, so child processes are never tracked or killed during cleanup.
**Proposed solution:** Add Unix child process enumeration using `pgrep -P <pid>` to find and kill child processes when the worker shuts down or restarts.
---
### #596 - SDK Crashes on Startup
Sometimes when the plugin tries to start its AI helper, it crashes immediately with "ProcessTransport not ready." It's a timing issue - the plugin tries to send data before the helper process is fully started up.
**Root cause:** The Claude Agent SDK spawns a subprocess, but the plugin immediately tries to write to stdin before the process has finished initializing. There's no retry mechanism.
**Proposed solution:** Add a retry wrapper with exponential backoff (100ms → 200ms → 400ms) around the SDK query call. If it fails with "ProcessTransport not ready," wait and try again up to 3 times.
---
### #587 - Observations Stop Being Saved
After you restart the worker (or it crashes), the plugin thinks it can resume an old session that doesn't exist anymore. The AI helper just sits there waiting instead of processing your work, so nothing gets saved.
**Root cause:** The `memorySessionId` persists in the database across worker restarts, but the actual SDK session is gone. The plugin tries to resume a non-existent session, and the SDK responds with "awaiting data" instead of processing.
**Proposed solution:** Track whether the `memorySessionId` was captured during the current worker run with a `memorySessionIdCapturedThisRun` flag. Only attempt to resume if this flag is true.
---
## High Priority (P1)
### #602 - Windows Won't Start
The plugin uses an old Windows command called `wmic` that Microsoft removed from Windows 11. So Windows users get errors and the plugin won't start properly.
**Root cause:** ProcessManager.ts uses `wmic process where "parentprocessid=X"` to enumerate child processes, but WMIC is deprecated and removed from modern Windows 11 builds.
**Proposed solution:** Replace WMIC with `tasklist /FI "PID eq X" /FO CSV` as the primary method, with PowerShell `Get-CimInstance Win32_Process` as a fallback.
---
### #588 - Unexpected API Charges
If you have an Anthropic API key in your project's `.env` file, the plugin silently uses it and charges your account. Users with Claude Max subscriptions were surprised by extra bills because the plugin found their API key and used it without asking.
**Root cause:** The default provider is set to `'claude'` in SettingsDefaultsManager.ts, and the Claude Agent SDK automatically discovers `ANTHROPIC_API_KEY` from environment variables. The plugin inherits the parent process environment, exposing any API keys.
**Proposed solution:** Either change the default provider to `'gemini'` (which has a free tier), or add a first-run warning that clearly states API costs will be incurred. Consider requiring explicit opt-in for Anthropic API usage.
---
### #591 - OpenRouter Provider Broken
When using OpenRouter as your AI provider, the plugin can't save observations because it's missing an internal ID that normally comes from Claude's API. OpenRouter doesn't provide this ID, and the plugin doesn't handle that.
**Root cause:** OpenRouterAgent.ts has no mechanism to capture or generate a `memorySessionId`. Unlike the Claude SDK which returns a `session_id` in responses, OpenRouter's API is stateless and doesn't provide session identifiers.
**Proposed solution:** Generate a UUID for `memorySessionId` at the start of `OpenRouterAgent.startSession()` before calling `processAgentResponse()`. The same fix is needed for GeminiAgent.ts.
---
### #598 - Plugin Messages in Your History
When you use `/resume` in Claude Code, you see a bunch of "Hello memory agent" messages that the plugin sent internally. These should be hidden from your conversation history but they're leaking through.
**Root cause:** The plugin yields messages with `session_id: session.contentSessionId` (the user's session) instead of `session.memorySessionId` (the plugin's internal session). This causes the SDK to associate plugin messages with the user's conversation.
**Proposed solution:** Change SDKAgent.ts line 289 to use `memorySessionId` instead of `contentSessionId`. Also consider removing or minimizing the `continuation_greeting` in code.json.
---
### #586 - Race Condition Loses Data
There's a timing bug where the plugin tries to save your observations before it has the session ID it needs. Instead of waiting, it just throws an error and your observations are lost.
**Root cause:** The async message generator yields messages concurrently with session ID capture. If `processAgentResponse()` runs before the first SDK message with `session_id` is processed, `memorySessionId` is still null and the hard error at ResponseProcessor.ts:73-75 throws.
**Proposed solution:** Replace the hard error with a wait/retry loop that polls for up to 5 seconds for `memorySessionId` to be captured. If still missing, generate a fallback UUID.
---
## Medium Priority (P2)
### #590 - Annoying Popup Window on Windows
When the plugin starts its vector database (Chroma) on Windows, a blank terminal window pops up and stays open. You have to manually close it every time.
**Root cause:** ChromaSync.ts attempts to set `windowsHide: true` in the transport options, but the MCP SDK's StdioClientTransport doesn't pass this option through to `child_process.spawn()`.
**Proposed solution:** Wrap the `uvx` command in a PowerShell call: `powershell -NoProfile -WindowStyle Hidden -Command "uvx ..."`. This pattern already works elsewhere in the codebase (ProcessManager.ts:271).
---
### #600 - Documentation Lies
The docs describe features that don't actually exist in the released version - they're only in beta branches. Users try to use documented features and they don't work.
**Root cause:** Documentation was written for features in beta branches that were never merged to main. The MCP migration removed the skills directory but docs still reference it. Several settings are documented but not in the validated settings list.
**Proposed solution:** Audit all docs and either add "Beta Only" badges to unimplemented features, or remove references entirely. Update architecture docs to reflect MCP-based search instead of skill-based.
---
### #597 - General Bug Report
A user posted 4 screenshots saying "too many bugs" after 2 days of frustration. It's basically a meta-issue confirming the other problems are real and affecting users.
**Root cause:** The user encountered multiple v9.0.0 regressions including ProcessTransport failures, worker startup issues, and session problems. The screenshots show error states but lack specific details.
**Proposed solution:** This is resolved by fixing the other issues. Consider adding a `/troubleshoot` command or better error reporting to help users provide actionable bug reports.
---
## Low Priority (P3)
### #599 - Windows Drive Root Error
If you run Claude Code from `C:\` (the drive root), the plugin crashes because it can't figure out what to call your "project." It's an edge case but easy to fix.
**Root cause:** user-message-hook.ts uses `path.basename(process.cwd())` directly, which returns an empty string for drive roots like `C:\`. The API rejects empty project names with a 400 error.
**Proposed solution:** Use the existing `getProjectName()` utility from `src/utils/project-name.ts` which already handles drive roots by returning `"drive-C"` style names.
---
## Summary by Release
| Release | Issues | Focus |
|---------|--------|-------|
| v9.0.1 | #603, #596, #587 | Critical stability fixes |
| v9.0.2 | #602, #588, #591, #598, #586 | Windows + provider fixes |
| v9.1.0 | #590, #600, #597 | Polish + documentation |
| v9.1.x | #599 | Edge case fix |

View File

@@ -0,0 +1,84 @@
# Open Issues Summary - January 7, 2026
This document provides an index of all open GitHub issues analyzed on 2026-01-07.
## Critical Priority (P0)
| Issue | Title | Severity | Report |
|-------|-------|----------|--------|
| #603 | Worker daemon leaks child claude processes | Critical | [Report](./issue-603-worker-daemon-leaks-child-processes.md) |
| #596 | ProcessTransport not ready for writing | Critical | [Report](./issue-596-processtransport-not-ready.md) |
| #587 | Observations not stored - SDK awaiting data | Critical | [Report](./issue-587-observations-not-stored.md) |
## High Priority (P1)
| Issue | Title | Severity | Report |
|-------|-------|----------|--------|
| #602 | PostToolUse worker-service failed (Windows) | Critical | [Report](./issue-602-posttooluse-worker-service-failed.md) |
| #588 | API key usage warning - unexpected charges | High | [Report](./issue-588-api-key-usage-warning.md) |
| #591 | OpenRouter memorySessionId capture failure | Critical | [Report](./issue-591-openrouter-memorysessionid-capture.md) |
| #598 | Conversation history pollution | High | [Report](./issue-598-conversation-history-pollution.md) |
| #586 | Race condition in memory_session_id capture | High | [Report](./issue-586-feature-request-unknown.md) |
| #597 | Multiple bugs reported (image-only) | High | [Report](./issue-597-too-many-bugs.md) |
## Medium Priority (P2)
| Issue | Title | Severity | Report |
|-------|-------|----------|--------|
| #590 | Windows Chroma terminal popup | Medium | [Report](./issue-590-windows-chroma-terminal-popup.md) |
| #600 | Documentation audit - features not implemented | Medium | [Report](./issue-600-documentation-audit-features-not-implemented.md) |
## Low Priority (P3)
| Issue | Title | Severity | Report |
|-------|-------|----------|--------|
| #599 | Windows drive root 400 error | Low | [Report](./issue-599-windows-drive-root-400-error.md) |
---
## Key Themes
### 1. v9.0.0 Regressions
Multiple issues (#596, #587, #586) relate to observation storage failures introduced in v9.0.0, primarily around:
- ProcessTransport race conditions
- Session ID capture timing
- Worker restart loops
### 2. Windows Platform Issues
Several Windows-specific bugs (#602, #590, #599):
- WMIC deprecated command usage
- Console window popups
- Path handling for drive roots
### 3. Session Management
Issues with session lifecycle (#603, #591, #598):
- Child process leaks
- Provider-specific session ID handling
- Message pollution in user history
### 4. Documentation Drift
Issue #600 identifies significant gap between documented and implemented features.
---
## Recommended Fix Order
1. **v9.0.1 Hotfix** (48 hours):
- #588 - Add API key usage warning (financial impact)
- #596 - ProcessTransport retry mechanism
- #587 - Stale session invalidation
2. **v9.0.2 Patch** (1 week):
- #603 - Orphan process reaper
- #602 - Windows WMIC replacement
- #591 - OpenRouter memorySessionId generation
3. **v9.1.0 Minor** (2 weeks):
- #598 - Session isolation improvements
- #590 - Windows console hiding
- #599 - Drive root path handling
- #600 - Documentation updates
---
*Generated: 2026-01-07 19:45 EST*

View File

@@ -3,165 +3,35 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
**2026-01-02--generator-failure-investigation.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36091 | 10:20 PM | 🔵 | Generator Failure Investigation - Chroma Vector Search Silent Failures | ~436 |
| #36079 | 10:10 PM | 🔴 | Fixed Generator Crashes from Silent Chroma Vector Search Failures | ~531 |
**2026-01-02--stuck-observations.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36004 | 8:14 PM | 🔵 | Comprehensive Investigation Report on Stuck Observations Problem | ~527 |
### Jan 3, 2026
**2026-01-04--session-id-refactor-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36643 | 10:56 PM | 🔵 | Session ID Refactor Test Failures Root Cause | ~513 |
| #36636 | 10:46 PM | 🟣 | Session ID Refactor Analysis Agent Completed Comprehensive Report | ~637 |
| #36626 | 10:44 PM | 🟣 | Session ID Refactor Failures Report Generated | ~569 |
**2026-01-04--gemini-agent-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36638 | 10:47 PM | ✅ | GeminiAgent Failures Report Manually Created After Agent Timeout | ~604 |
**2026-01-04--session-store-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36635 | 10:46 PM | 🟣 | SessionStore Analysis Agent Completed Report Generation | ~545 |
| #36634 | " | ✅ | SessionStore Failures Report Generated With Test Fix Recommendations | ~595 |
**2026-01-04--logger-coverage-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36633 | 10:46 PM | ✅ | Logger Coverage Failures Report Generated | ~559 |
| #36623 | 10:44 PM | 🟣 | Logger Coverage Failures Report Generated | ~249 |
**2026-01-04--session-id-validation-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36628 | 10:44 PM | 🟣 | Session ID Validation Failures Report Generated | ~690 |
**2026-01-04--test-suite-report.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36609 | 10:39 PM | 🟣 | Comprehensive Test Suite Report Generated | ~563 |
**reports**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36599 | 10:37 PM | 🔵 | Reports Directory Structure Confirmed | ~203 |
**2026-01-02--generator-failure-investigation.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**2026-01-03--observation-saving-failure.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36113 | 3:58 PM | 🔴 | Fixed FOREIGN KEY Constraint Failure in Observation Storage | ~448 |
### Jan 4, 2026
**2026-01-04--issue-511-gemini-model-missing.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | ✅ | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36827 | 1:03 AM | ✅ | Branch diff shows 1,293 insertions and 98 deletions across 15 files | ~464 |
| #36781 | 12:45 AM | 🔵 | Complete GeminiAgent Model Configuration Gap Analysis | ~552 |
| #36776 | 12:43 AM | 🔵 | Issue #511 Analysis Document Located | ~459 |
| #36759 | 12:34 AM | ✅ | Created Issue #511 Analysis Report | ~304 |
**2026-01-04--issue-517-windows-powershell-analysis.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36779 | 12:44 AM | 🔵 | ProcessManager Windows PowerShell Functions Complete Analysis | ~550 |
| #36720 | 12:15 AM | 🔵 | Issue #517 Windows PowerShell Analysis Completed | ~631 |
| #36718 | " | 🔵 | Issue #517 Analysis - Windows PowerShell Variable Escaping Bug | ~482 |
**2026-01-04--issue-531-export-type-duplication.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36760 | 12:34 AM | ✅ | Created Issue #531 Report: Export Script Type Duplication | ~430 |
**2026-01-04--gemini-agent-failures.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36751 | 12:32 AM | 🔵 | Gemini-Related Files Located Across Project | ~242 |
**reports**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36748 | 12:31 AM | 🔵 | Existing GitHub Issue Reports Located | ~271 |
**2026-01-04--issue-527-uv-homebrew-analysis.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36721 | 12:15 AM | 🔵 | Issue #527 UV Homebrew Path Missing on Apple Silicon | ~492 |
| #36719 | " | 🔵 | Issue #527 uv Homebrew Detection Missing on Apple Silicon Macs | ~526 |
**2026-01-04--issue-514-orphaned-sessions-analysis.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36717 | 12:14 AM | 🔵 | Issue #514 Orphaned Sessions Analysis Completed | ~723 |
| #36716 | 12:13 AM | 🔵 | Issue #514 Orphaned .jsonl Session Files Analysis | ~616 |
**2026-01-04--issue-532-memory-leak-analysis.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36714 | 12:12 AM | 🔵 | Memory Leak Analysis Report for Issue #532 Generated | ~531 |
| #36712 | 12:11 AM | 🔵 | Memory Leak Analysis for Issue #532 Documented | ~646 |
**2026-01-04--issue-520-stuck-messages-analysis.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36713 | 12:11 AM | 🔵 | Issue #520 Stuck Messages Already Resolved | ~569 |
| #36711 | " | 🔵 | Issue #520 Stuck Messages Analysis - Already Resolved | ~526 |
**2026-01-02--stuck-observations.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36710 | 12:07 AM | 🔵 | Stuck Observations Analysis - Six Critical Lifecycle Gaps | ~677 |
### Jan 5, 2026
**2026-01-05--issue-544-mem-search-hint-claude-code.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37613 | 5:31 PM | 🔵 | PR #558 Review Feedback Analysis | ~544 |
| #37555 | 4:49 PM | 🔵 | Issue #544 Message Locations and Fix Pattern Documented | ~463 |
| #37545 | 4:47 PM | ✅ | Issue #544 Analysis Report Created for mem-search Skill Messaging Problem | ~480 |
| #37962 | 8:18 PM | 🔴 | Fixed SessionStart hook crash when stdin is undefined | ~440 |
### Jan 7, 2026
**2026-01-05--issue-555-windows-hooks-ipc-false.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37558 | 4:49 PM | 🔵 | Issue #555 Windows Hook Execution Patterns and Fix Strategy Documented | ~510 |
**2026-01-05--issue-545-formattool-json-parse-crash.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37557 | 4:49 PM | 🔵 | Issue #545 Bug Location and Fix Pattern Documented | ~462 |
**2026-01-05--issue-543-slash-command-unavailable.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37548 | 4:48 PM | | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
**2026-01-05--issue-557-settings-module-loader-error.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37547 | 4:47 PM | | Issue #557 Analysis Report Created for Plugin Startup Failure | ~491 |
### Jan 6, 2026
**2026-01-06--windows-woes-comprehensive-report.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38109 | 12:16 AM | ✅ | Comprehensive Windows Woes Report Generated from Memory Search | ~826 |
| #38475 | 10:31 PM | ⚖️ | Log Level Philosophy: Error-Adjacent Messages Promoted to ERROR | ~412 |
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38445 | 10:26 PM | 🔵 | DEBUG Level Logging: SessionRoutes Line 211 Error-During-Recovery Pattern | ~500 |
| #38442 | 10:25 PM | 🔵 | Log Audit Contains 409 Source File Log Entries | ~293 |
| #38441 | " | 🔵 | DEBUG-level logging patterns for diagnostics and non-critical operations | ~595 |
| #38439 | " | 🔵 | Log Audit Shows SessionRoutes.ts Has Two WARN Messages for Generator Failures | ~493 |
| #38438 | " | 🔵 | WARN Level Log Patterns: Graceful Degradation and Fallback Behavior | ~539 |
| #38437 | 10:24 PM | 🔵 | Claude-mem core functionality and logging patterns identified | ~710 |
| #38428 | " | 🔵 | Log level audit report structure and content examined | ~559 |
| #38425 | " | ⚖️ | Log Level Architecture: Fail-Critical Over Fail-Fast for Chroma | ~467 |
| #38416 | 10:22 PM | 🔵 | ChromaDB Is Critical Not Optional - Log Audit Findings Challenged | ~405 |
| #38405 | 10:07 PM | ⚖️ | DEBUG Log Level Analysis - One Message Requires WARN Promotion | ~819 |
| #38404 | 10:06 PM | ⚖️ | Log Level Audit Analysis - WARN to ERROR Promotion Criteria Established | ~769 |
| #38403 | 10:04 PM | 🔵 | Log Level Audit - INFO and DEBUG Level Messages Catalogued | ~688 |
| #38402 | 10:03 PM | 🔵 | Log Level Audit Report Analysis - Critical Error Messages Identified | ~642 |
| #38401 | 10:00 PM | 🔵 | Enhanced Audit Report Reveals Error Logging Patterns and Message Extraction Issues | ~498 |
| #38394 | 9:58 PM | ✅ | Created Log Level Audit Report Documentation | ~319 |
| #38393 | " | ✅ | Enhanced Log Audit Report Format with Component Tags and Full Logger Calls | ~393 |
| #38386 | 9:56 PM | ✅ | Log Audit Report Generated and Saved to Documentation | ~442 |
| #38385 | " | ✅ | Log Level Audit Report Saved to Documentation | ~379 |
| #38251 | 7:46 PM | 🔵 | Comprehensive Windows Platform Issues Report | ~982 |
</claude-mem-context>

View File

@@ -0,0 +1,507 @@
# Issue #586: Race Condition in memory_session_id Capture
**Report Date:** 2026-01-07
**Issue:** [#586](https://github.com/thedotmack/claude-mem/issues/586)
**Reporter:** rocky2431
**Environment:** claude-mem 9.0.0, macOS Darwin 24.6.0, Node v22.x / Bun 1.x
---
## 1. Executive Summary
This issue describes a critical race condition where new sessions frequently have an empty (NULL) `memory_session_id` in the `sdk_sessions` table. This prevents observations from being stored, as the `ResponseProcessor` requires a valid `memorySessionId` before processing agent responses.
**Key Finding:** The race condition occurs because session initialization via `handleSessionInitByClaudeId()` creates the session with a NULL `memory_session_id`, but the SDK agent may not have responded yet to provide its session ID when subsequent `PostToolUse` hooks attempt to store observations.
**Error Message:**
```
Cannot store observations: memorySessionId not yet captured
```
**Severity:** Critical
**Priority:** P1
**Impact:** Sessions with NULL `memory_session_id` cannot store any observations, leading to data loss and incomplete session history.
---
## 2. Problem Analysis
### 2.1 Error Manifestation
The error originates from `ResponseProcessor.ts` (line 73-75):
```typescript
// CRITICAL: Must use memorySessionId (not contentSessionId) for FK constraint
if (!session.memorySessionId) {
throw new Error('Cannot store observations: memorySessionId not yet captured');
}
```
### 2.2 Observed Symptoms
1. **Log Evidence:**
```log
[2026-01-07 04:02:39.872] [INFO ] [SESSION] [session-14379] Session initialized
{project=claude-task-master, contentSessionId=a48d7f90-27e4-4a1d-b379-bf2195ee333e,
queueDepth=0, hasGenerator=false}
```
Note: `contentSessionId` is present but `memorySessionId` is missing.
2. **Database State:**
```sql
SELECT id, memory_session_id, project FROM sdk_sessions ORDER BY id DESC LIMIT 5;
14379 | (NULL) | claude-task-master -- Missing!
14293 | 090b5397-... | .claude -- OK
14285 | (NULL) | .claude -- Missing!
```
3. **Queue Accumulation:**
- Observations are enqueued to `pending_messages` table
- Hundreds of unprocessed items accumulate
- Only user prompts are recorded, no AI analysis
### 2.3 Race Condition Timeline
```
Time T0: SessionStart hook triggers
└─> new-hook.ts calls /api/sessions/init
└─> createSDKSession() creates row with memory_session_id = NULL
Time T1: PostToolUse hook triggers (user action)
└─> save-hook.ts calls /api/sessions/observations
└─> Observation queued to pending_messages
Time T2: SDK Agent generator starts
└─> Waiting for first message from Claude SDK
Time T3: First SDK message arrives (RACE CONDITION WINDOW)
└─> updateMemorySessionId() called with captured ID
└─> Database updated: memory_session_id = "sdk-gen-abc123"
Time T4: SDK Agent attempts to process queued observations
└─> processAgentResponse() checks session.memorySessionId
└─> If NULL (not yet updated): ERROR thrown
```
**The Problem:** If `PostToolUse` events arrive during the window between session creation (T0) and SDK session ID capture (T3), the `ResponseProcessor` will fail because `memorySessionId` is still NULL.
---
## 3. Technical Details
### 3.1 Session ID Architecture
Claude-mem uses a dual session ID system (documented in `docs/SESSION_ID_ARCHITECTURE.md`):
| ID | Purpose | Source | Initial Value |
|----|---------|--------|---------------|
| `contentSessionId` | User's Claude Code conversation ID | Hook system | Set immediately |
| `memorySessionId` | Memory agent's internal session ID | SDK response | NULL (captured later) |
### 3.2 Session Creation Flow
**File:** `src/services/sqlite/sessions/create.ts` (lines 24-47)
```typescript
export function createSDKSession(
db: Database,
contentSessionId: string,
project: string,
userPrompt: string
): number {
// Pure INSERT OR IGNORE - no updates, no complexity
// NOTE: memory_session_id starts as NULL. It is captured by SDKAgent from the first SDK
// response and stored via updateMemorySessionId(). CRITICAL: memory_session_id must NEVER
// equal contentSessionId - that would inject memory messages into the user's transcript!
db.prepare(`
INSERT OR IGNORE INTO sdk_sessions
(content_session_id, memory_session_id, project, user_prompt, started_at, started_at_epoch, status)
VALUES (?, NULL, ?, ?, ?, ?, 'active')
`).run(contentSessionId, project, userPrompt, now.toISOString(), nowEpoch);
// ...
}
```
### 3.3 Memory Session ID Capture
**File:** `src/services/worker/SDKAgent.ts` (lines 117-141)
```typescript
// Process SDK messages
for await (const message of queryResult) {
// Capture memory session ID from first SDK message (any type has session_id)
if (!session.memorySessionId && message.session_id) {
session.memorySessionId = message.session_id;
// Persist to database for cross-restart recovery
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
message.session_id
);
// ... verification logging ...
}
// ...
}
```
### 3.4 Response Processor Validation
**File:** `src/services/worker/agents/ResponseProcessor.ts` (lines 72-75)
```typescript
// CRITICAL: Must use memorySessionId (not contentSessionId) for FK constraint
if (!session.memorySessionId) {
throw new Error('Cannot store observations: memorySessionId not yet captured');
}
```
### 3.5 Session Manager Initialization
**File:** `src/services/worker/SessionManager.ts` (lines 127-143)
```typescript
// Create active session
// Load memorySessionId from database if previously captured (enables resume across restarts)
session = {
sessionDbId,
contentSessionId: dbSession.content_session_id,
memorySessionId: dbSession.memory_session_id || null, // NULL initially!
// ...
};
```
---
## 4. Impact Assessment
### 4.1 Direct Impact
| Impact Area | Description |
|------------|-------------|
| **Data Loss** | Observations queued during race window are never stored |
| **Queue Growth** | `pending_messages` table grows unbounded |
| **User Experience** | Session history incomplete - only prompts, no analysis |
| **System Load** | Repeated retry attempts consume resources |
### 4.2 Frequency
The issue appears **intermittent** - some sessions initialize correctly while others fail. The race condition depends on:
- System load
- Claude SDK response latency
- Hook timing relative to SDK startup
### 4.3 Related Issues
- **Issue #520** (CLOSED): Stuck messages in 'processing' status - similar queue recovery problem
- **Issue #591**: OpenRouter Agent fails to capture memorySessionId - architectural gap for stateless providers
---
## 5. Root Cause Analysis
### 5.1 Primary Root Cause
**Architectural Timing Gap:** The session initialization API (`/api/sessions/init`) creates sessions with a NULL `memory_session_id`, expecting the SDK agent to capture it from the first response. However, there is no synchronization mechanism to prevent observation processing before this capture occurs.
### 5.2 Contributing Factors
1. **Asynchronous SDK Agent Startup:** The generator starts asynchronously without blocking the hook response
2. **No Capture Wait Mechanism:** Observations are queued immediately without waiting for memorySessionId capture
3. **Strict Validation in ResponseProcessor:** The processor throws an error rather than handling the NULL case gracefully
4. **No Retry Logic:** Failed observations due to missing memorySessionId are not retried after capture
### 5.3 Timing Window Analysis
```
Hook Execution Timeline:
├─ new-hook.ts (UserPromptSubmit)
│ ├─ POST /api/sessions/init → createSDKSession(memory_session_id=NULL)
│ └─ POST /sessions/{id}/init → startSession() [async, non-blocking]
├─ [RACE CONDITION WINDOW OPENS]
│ └─ SDK agent waiting for Claude response
├─ save-hook.ts (PostToolUse) ← CAN TRIGGER DURING WINDOW
│ └─ POST /api/sessions/observations
│ └─ Queued, will fail when processed
├─ [SDK FIRST MESSAGE ARRIVES]
│ └─ updateMemorySessionId(captured_id)
│ └─ Database updated, session.memorySessionId set
├─ [RACE CONDITION WINDOW CLOSES]
└─ Subsequent observations process successfully
```
---
## 6. Recommended Solutions
### 6.1 Solution A: Retry Mechanism in ResponseProcessor (Recommended)
If `memorySessionId` is not available, wait briefly with exponential backoff:
```typescript
// In processAgentResponse():
async function waitForMemorySessionId(
session: ActiveSession,
dbManager: DatabaseManager,
maxRetries: number = 5,
baseDelayMs: number = 100
): Promise<boolean> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
if (session.memorySessionId) return true;
// Check database for updates
const dbSession = dbManager.getSessionById(session.sessionDbId);
if (dbSession?.memory_session_id) {
session.memorySessionId = dbSession.memory_session_id;
return true;
}
await new Promise(resolve => setTimeout(resolve, baseDelayMs * Math.pow(2, attempt)));
}
return false;
}
// Usage:
const captured = await waitForMemorySessionId(session, dbManager);
if (!captured) {
throw new Error('Cannot store observations: memorySessionId not yet captured after retries');
}
```
**Pros:**
- Non-breaking change
- Handles timing variations gracefully
- Minimal code modification
**Cons:**
- Adds latency in worst case
- Polling-based solution
### 6.2 Solution B: Lazy Capture on First PostToolUse
Capture `memorySessionId` on the first `PostToolUse` if not already set:
```typescript
// In handleObservationsByClaudeId():
if (!session.memorySessionId && session.contentSessionId) {
// Generate a placeholder that will be updated when SDK responds
const tempId = `pending-${session.contentSessionId}`;
session.memorySessionId = tempId;
store.updateMemorySessionId(sessionDbId, tempId);
logger.warn('SESSION', 'Generated temporary memorySessionId', { tempId });
}
```
**Pros:**
- Immediate resolution
- No retry delays
**Cons:**
- Temporary IDs may cause confusion
- Requires updating when real ID is captured
### 6.3 Solution C: Use contentSessionId as Fallback
For initial observations before SDK capture, use `contentSessionId`:
```typescript
// In processAgentResponse():
const effectiveMemorySessionId = session.memorySessionId || session.contentSessionId;
```
**Pros:**
- Simple implementation
- No timing issues
**Cons:**
- **Violates architectural principle** that memorySessionId should differ from contentSessionId
- Risk of FK constraint issues
- May cause resume problems
### 6.4 Solution D: Block Until memorySessionId is Captured
Modify `handleObservationsByClaudeId` to wait for SDK capture:
```typescript
// In handleObservationsByClaudeId():
const session = this.sessionManager.getSession(sessionDbId);
if (!session?.memorySessionId) {
// Return a "pending" response, client should retry
res.status(202).json({
status: 'pending',
reason: 'awaiting_memory_session_id',
retryAfterMs: 500
});
return;
}
```
**Pros:**
- Explicit handling
- Client-controlled retry
**Cons:**
- Requires hook changes
- May cause hook timeout
### 6.5 Recommended Approach
**Solution A** is recommended because:
1. Handles the race condition transparently
2. Minimal impact on existing code
3. Self-healing behavior (retries until successful)
4. Maintains architectural integrity
5. Low regression risk
---
## 7. Priority/Severity Assessment
### 7.1 Severity Matrix
| Factor | Assessment |
|--------|------------|
| **Data Loss** | High - Observations lost during race window |
| **Functionality** | Partial - Some sessions work, some don't |
| **Frequency** | Intermittent - Depends on system timing |
| **Workaround** | Manual SQL fix available |
| **Affected Users** | All users under specific timing conditions |
### 7.2 Priority Assignment
**Priority: P1 (High)**
Rationale:
- Silent data loss is occurring
- Affects core functionality (observation storage)
- Unpredictable - users may not know data is being lost
- Fix is straightforward with low regression risk
### 7.3 Recommended Timeline
| Action | Timeline |
|--------|----------|
| Implement Solution A | 2-4 hours |
| Unit tests | 1 hour |
| Integration tests | 1 hour |
| Code review | 30 minutes |
| Release | Same day |
---
## 8. Workaround
Users experiencing this issue can manually fix affected sessions:
```sql
-- Find sessions with missing memory_session_id
SELECT id, content_session_id, project
FROM sdk_sessions
WHERE memory_session_id IS NULL;
-- Option 1: Use content_session_id as memory_session_id (not recommended)
-- WARNING: May cause issues with session resume
UPDATE sdk_sessions
SET memory_session_id = content_session_id
WHERE id = <sessionDbId> AND memory_session_id IS NULL;
-- Option 2: Generate a unique ID
UPDATE sdk_sessions
SET memory_session_id = 'manual-' || content_session_id
WHERE id = <sessionDbId> AND memory_session_id IS NULL;
```
**Important:** After applying the workaround, the worker must be restarted to pick up the new `memory_session_id` values.
---
## 9. Testing Recommendations
### 9.1 Unit Tests
```typescript
describe('ResponseProcessor memorySessionId handling', () => {
it('should wait for memorySessionId capture with retry', async () => {
const session = createMockSession({ memorySessionId: null });
// Simulate delayed capture
setTimeout(() => {
session.memorySessionId = 'captured-id';
}, 200);
await expect(
processAgentResponse(text, session, dbManager, sessionManager, worker, 0, null, 'Test')
).resolves.not.toThrow();
});
it('should throw after max retries if memorySessionId never captured', async () => {
const session = createMockSession({ memorySessionId: null });
await expect(
processAgentResponse(text, session, dbManager, sessionManager, worker, 0, null, 'Test')
).rejects.toThrow('memorySessionId not yet captured after retries');
});
});
```
### 9.2 Integration Tests
```typescript
describe('Session initialization race condition', () => {
it('should handle rapid PostToolUse events during SDK startup', async () => {
// Create session
const sessionDbId = store.createSDKSession(contentSessionId, project, prompt);
// Immediately queue observations (before SDK responds)
for (let i = 0; i < 5; i++) {
sessionManager.queueObservation(sessionDbId, {
tool_name: 'Read',
tool_input: { file_path: '/test.txt' },
tool_response: { content: 'test' },
prompt_number: 1,
cwd: '/test'
});
}
// Start SDK agent (will capture memorySessionId)
await sdkAgent.startSession(session, worker);
// Verify all observations were stored
const stored = db.prepare('SELECT COUNT(*) as count FROM observations WHERE memory_session_id = ?')
.get(session.memorySessionId);
expect(stored.count).toBeGreaterThanOrEqual(5);
});
});
```
---
## 10. Related Files
| File | Relevance |
|------|-----------|
| `src/services/worker/agents/ResponseProcessor.ts` | Error origin (line 73-75), primary fix location |
| `src/services/worker/SessionManager.ts` | Session initialization with NULL memorySessionId |
| `src/services/worker/SDKAgent.ts` | memorySessionId capture logic |
| `src/services/sqlite/sessions/create.ts` | Session creation with NULL memory_session_id |
| `src/hooks/new-hook.ts` | Session initialization hook |
| `src/hooks/save-hook.ts` | PostToolUse observation queueing |
| `docs/SESSION_ID_ARCHITECTURE.md` | Architecture documentation |
---
## 11. Conclusion
Issue #586 describes a critical race condition in the session initialization process where `memory_session_id` is not captured before observations are processed. This results in silent data loss as observations fail to store with the error "Cannot store observations: memorySessionId not yet captured".
The recommended fix is to implement a retry mechanism in `ResponseProcessor.processAgentResponse()` that waits for the `memorySessionId` to be captured, with exponential backoff. This approach:
- Maintains the existing architectural integrity
- Handles timing variations gracefully
- Has low regression risk
- Is straightforward to implement and test
**Immediate Action Required:** Implement Solution A (Retry Mechanism) and release a hotfix to prevent ongoing data loss.

View File

@@ -0,0 +1,337 @@
# Technical Report: Issue #587 - Observations Not Being Stored
**Issue:** v9.0.0: Observations not being stored - SDK agent stuck on 'Awaiting tool execution data'
**Author:** chuck-boudreau
**Created:** 2026-01-07
**Report Date:** 2026-01-07
**Status:** Open
**Affected Version:** 9.0.0
**Environment:** macOS (Darwin 25.1.0)
---
## 1. Executive Summary
After upgrading to claude-mem v9.0.0, users report that observations are not being stored in the database. The SDK agent responds with "Ready to observe. Awaiting tool execution data from the primary session" instead of processing tool calls and generating observations. Investigation reveals a **two-part failure mode**:
1. **Primary Issue:** The SDK agent receives tool execution data but fails to process it into observations, returning a generic "awaiting data" message despite receiving valid input.
2. **Secondary Issue (Resolved):** A version mismatch between plugin (9.0.0) and worker (8.5.9) was causing an infinite restart loop, which was fixed in commit `e22e2bfc`. However, **even after resolving the restart loop, the observation storage issue persists**.
This report analyzes both issues, identifies potential root causes, and proposes solutions.
---
## 2. Problem Analysis
### 2.1 Symptom Description
The user reports the following behavior after upgrading to v9.0.0:
```
[INFO ] [SDK ] [session-1] <- Response received (72 chars) {promptNumber=57} Ready to observe. Awaiting tool execution data from the primary session.
[INFO ] [DB ] [session-1] STORED | sessionDbId=1 | memorySessionId=xxx | obsCount=0 | obsIds=[] | summaryId=none
```
Key observations:
- The SDK agent is starting correctly (`Generator auto-starting`)
- Tool executions are being received (`PostToolUse: Bash(cat ~/.claude-mem/settings.json)`)
- Messages are being queued (`ENQUEUED | messageId=596 | type=observation`)
- Messages are being claimed by the agent (`CLAIMED | messageId=596`)
- **BUT:** The agent returns "Ready to observe. Awaiting tool execution data" instead of actual observations
- Result: `obsCount=0` persists across all tool calls
### 2.2 Version Mismatch Issue (Resolved)
The user also encountered a version mismatch causing infinite restarts:
```
[INFO ] [SYSTEM] Worker version mismatch detected - auto-restarting {pluginVersion=9.0.0, workerVersion=8.5.9}
```
**Resolution:** This issue was fixed in commit `e22e2bfc` (PR #567) by:
1. Updating `plugin/package.json` from 8.5.10 to 9.0.0
2. Rebuilding all hooks and worker service with correct version injection
3. Adding version consistency tests
However, the user reports that **even after resolving the restart loop, observations still weren't being created**.
---
## 3. Technical Details
### 3.1 Architecture Overview
The claude-mem observation pipeline works as follows:
```
User Session -> PostToolUse Hook -> Worker HTTP API -> Session Queue -> SDK Agent -> Database
(save-hook.ts) (/api/sessions/ (SessionManager) (SDKAgent.ts)
observations)
```
### 3.2 SDK Agent Prompt System
The SDK agent uses a mode-based prompt system loaded from `/plugin/modes/code.json`:
1. **Initial Prompt (`buildInitPrompt`)**: Full initialization with system identity, observer role, recording focus
2. **Continuation Prompt (`buildContinuationPrompt`)**: For subsequent tool observations in the same session
3. **Observation Prompt (`buildObservationPrompt`)**: Wraps tool execution data in XML format
**Key files:**
- `/src/services/worker/SDKAgent.ts` - Agent implementation (lines 100-213)
- `/src/sdk/prompts.ts` - Prompt building functions (lines 29-235)
- `/plugin/modes/code.json` - Mode configuration with prompt templates
### 3.3 Message Flow Analysis
From the logs, the flow appears correct up to SDK query:
```
1. PostToolUse hook fires -> /api/sessions/observations
2. SessionManager.queueObservation() persists to PendingMessageStore
3. EventEmitter notifies SDK agent
4. SDK agent yields observation prompt to Claude SDK
5. Claude SDK returns response -> "Ready to observe. Awaiting tool execution data"
6. No observations parsed -> obsCount=0
```
### 3.4 Suspicious Log Entry
```
promptType=CONTINUATION
lastPromptNumber=57
```
The `promptNumber=57` suggests this is a continuation of an existing session, not a fresh start. The `CONTINUATION` prompt type is used when `session.lastPromptNumber > 1`.
**Potential Issue:** If the SDK session context was lost (e.g., due to the restart loop), the `memorySessionId` may be stale, but the system is attempting to resume a session that no longer exists in the Claude SDK's context.
### 3.5 Code Analysis: Resume Logic
From `SDKAgent.ts` (lines 71-114):
```typescript
// CRITICAL: Only resume if:
// 1. memorySessionId exists (was captured from a previous SDK response)
// 2. lastPromptNumber > 1 (this is a continuation within the same SDK session)
// On worker restart or crash recovery, memorySessionId may exist from a previous
// SDK session but we must NOT resume because the SDK context was lost.
const hasRealMemorySessionId = !!session.memorySessionId;
const queryResult = query({
prompt: messageGenerator,
options: {
model: modelId,
// Only resume if BOTH: (1) we have a memorySessionId AND (2) this isn't the first prompt
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
// ...
}
});
```
**Critical Finding:** The code attempts to resume the SDK session if `memorySessionId` exists AND `lastPromptNumber > 1`. However, if the worker restarted (due to version mismatch), the SDK context is lost but the `memorySessionId` may still exist in the database from a previous session.
The code at lines 92-98 attempts to detect this:
```typescript
// INIT prompt - never resume even if memorySessionId exists (stale from previous session)
if (hasStaleMemoryId) {
logger.warn('SDK', `Skipping resume for INIT prompt despite existing memorySessionId=${session.memorySessionId} - SDK context was lost (worker restart or crash recovery)`);
}
```
But this only applies when `lastPromptNumber === 1`. If `lastPromptNumber > 1`, the code still attempts to resume with a potentially stale `memorySessionId`.
---
## 4. Impact Assessment
### 4.1 Severity: **Critical**
- **Data Loss:** Observations are not being persisted, resulting in complete loss of session memory
- **Core Functionality Broken:** The primary purpose of claude-mem (persistent memory) is non-functional
- **User Experience:** Users see no value from the plugin after upgrade
### 4.2 Scope
- **Affected Users:** All users who upgraded to v9.0.0 and had existing sessions
- **Trigger Condition:** Appears to occur when:
1. Worker restarts (due to version mismatch or other reasons)
2. Session has existing `memorySessionId` in database
3. Session has `lastPromptNumber > 1`
### 4.3 Workaround
Users can work around by:
1. Clearing the database: `rm ~/.claude-mem/claude-mem.db`
2. Starting fresh sessions
However, this results in loss of all historical observations.
---
## 5. Root Cause Analysis
### 5.1 Primary Hypothesis: Stale Session Resume
**Root Cause:** The SDK agent attempts to resume a session using a `memorySessionId` that no longer exists in the Claude SDK's context (because the SDK process was terminated during the restart loop).
**Evidence:**
1. `promptNumber=57` suggests continuation of existing session
2. `promptType=CONTINUATION` indicates resume path is being taken
3. The response "Ready to observe. Awaiting tool execution data" suggests the SDK received a continuation prompt without the necessary context
**Code Path:**
1. Worker restarts due to version mismatch
2. Session is reloaded from database with `memory_session_id` and `lastPromptNumber=57`
3. `SDKAgent.startSession()` evaluates `hasRealMemorySessionId=true` and `lastPromptNumber > 1`
4. Adds `resume: memorySessionId` to query options
5. Claude SDK attempts to resume non-existent session
6. Claude SDK responds with generic "awaiting data" message instead of processing observations
### 5.2 Secondary Hypothesis: Prompt Format Issue
The SDK agent might not be receiving the observation data in the expected format. The `buildObservationPrompt` function formats tool data as:
```xml
<observed_from_primary_session>
<what_happened>Bash</what_happened>
<occurred_at>2026-01-07T...</occurred_at>
<parameters>...</parameters>
<outcome>...</outcome>
</observed_from_primary_session>
```
If the Claude model doesn't recognize this as actionable tool data (expecting a different format), it might respond with the generic message.
### 5.3 Tertiary Hypothesis: Mode Configuration Issue
The mode system loads configuration from `/plugin/modes/code.json`. If the mode fails to load or loads incorrectly, the prompts may be malformed.
From `ModeManager.ts`:
```typescript
loadMode(modeId: string): ModeConfig {
// Falls back to 'code' if mode not found
// Throws only if 'code.json' is missing
}
```
---
## 6. Recommended Solutions
### 6.1 Immediate Fix: Invalidate Stale Session IDs on Worker Restart
**Priority:** Critical
**Effort:** Low
**File:** `src/services/worker/SDKAgent.ts`
Add detection for worker restart scenarios and invalidate stale `memorySessionId`:
```typescript
// Before starting SDK query, check if this is a recovery scenario
// If worker restarted but session was mid-flight, the SDK context is lost
// We should start fresh instead of attempting to resume
if (session.memorySessionId && !isWorkerSameProcess(session.memorySessionId)) {
logger.warn('SDK', 'Invalidating stale memorySessionId due to worker restart', {
sessionDbId: session.sessionDbId,
staleMemorySessionId: session.memorySessionId
});
session.memorySessionId = null;
this.dbManager.getSessionStore().updateMemorySessionId(session.sessionDbId, null);
}
```
### 6.2 Short-Term Fix: Add Resume Validation
**Priority:** High
**Effort:** Medium
**File:** `src/services/worker/SDKAgent.ts`
Before attempting resume, validate that the session exists in the SDK:
```typescript
// Validate memorySessionId before attempting resume
if (hasRealMemorySessionId && session.lastPromptNumber > 1) {
const isValidSession = await this.validateSDKSession(session.memorySessionId);
if (!isValidSession) {
logger.warn('SDK', 'memorySessionId no longer valid, starting fresh', {
sessionDbId: session.sessionDbId,
invalidMemorySessionId: session.memorySessionId
});
session.memorySessionId = null;
session.lastPromptNumber = 1; // Reset to trigger INIT prompt
}
}
```
### 6.3 Long-Term Fix: Add Worker Instance Tracking
**Priority:** Medium
**Effort:** High
**Files:** Multiple
Track worker instance ID in the database to detect restart scenarios:
1. Generate unique worker instance ID on startup
2. Store with each session's `memorySessionId`
3. On session load, compare worker instance ID
4. If mismatch, invalidate `memorySessionId` and restart fresh
### 6.4 Additional Recommendations
1. **Add diagnostic logging:** Log the full prompt being sent to SDK for debugging
2. **Add retry logic:** If SDK returns generic response, retry with INIT prompt
3. **Add health check:** Validate SDK session state before processing observations
4. **Update VERSION_FIX.md:** Document the observation storage issue as a related symptom
---
## 7. Priority/Severity Assessment
| Aspect | Rating | Justification |
|--------|--------|---------------|
| **Severity** | Critical | Core functionality completely broken |
| **Impact** | High | All v9.0.0 users with existing sessions affected |
| **Urgency** | High | Users currently losing all observation data |
| **Complexity** | Medium | Root cause identified, fix is localized |
| **Risk** | Low | Fix is additive, doesn't change happy path |
### Recommended Priority: **P0 - Critical**
This should be addressed immediately with a patch release (v9.0.1).
---
## 8. References
### Relevant Files
- `/src/services/worker/SDKAgent.ts` - SDK agent implementation
- `/src/sdk/prompts.ts` - Prompt building functions
- `/src/services/worker/SessionManager.ts` - Session lifecycle management
- `/src/services/infrastructure/HealthMonitor.ts` - Version checking
- `/docs/VERSION_FIX.md` - Documentation of version mismatch fix
### Related Issues
- PR #567 - Fix version mismatch causing infinite worker restart loop
- Commit `e22e2bfc` - Version mismatch fix
### Test Files
- `/tests/infrastructure/version-consistency.test.ts` - Version consistency tests
---
## 9. Appendix: Full Log Excerpt
```
[INFO ] [HOOK ] -> PostToolUse: Bash(cat ~/.claude-mem/settings.json) {workerPort=37777}
[INFO ] [HTTP ] -> POST /api/sessions/observations {requestId=POST-xxx}
[INFO ] [QUEUE ] [session-1] ENQUEUED | sessionDbId=1 | messageId=596 | type=observation | tool=Bash(...) | depth=1
[INFO ] [SESSION] [session-1] Generator auto-starting (observation) using Claude SDK {queueDepth=0, historyLength=0}
[INFO ] [SDK ] Starting SDK query {sessionDbId=1, ..., lastPromptNumber=57, isInitPrompt=false, promptType=CONTINUATION}
[INFO ] [SDK ] Creating message generator {..., promptType=CONTINUATION}
[INFO ] [QUEUE ] [session-1] CLAIMED | sessionDbId=1 | messageId=596 | type=observation
[INFO ] [SDK ] [session-1] <- Response received (72 chars) {promptNumber=57} Ready to observe. Awaiting tool execution data from the primary session.
[INFO ] [DB ] [session-1] STORED | sessionDbId=1 | ... | obsCount=0 | obsIds=[] | summaryId=none
```

View File

@@ -0,0 +1,434 @@
# Issue #588: Unexpected API Charges from ANTHROPIC_API_KEY Discovery
**Date:** January 7, 2026
**Status:** INVESTIGATION COMPLETE - Critical UX/Financial Issue
**Priority:** HIGH
**Labels:** bug, financial-impact, ux
**Author:** imkane
**Version Affected:** 9.0.0 and earlier
---
## Executive Summary
A user with a Claude Max subscription ($100/month) began receiving unexpected "Auto-recharge credits" invoice emails from Anthropic after installing the claude-mem plugin. The plugin discovered an `ANTHROPIC_API_KEY` in a `.env` file in the project root and used it for AI operations (observation compression, summary generation), causing direct API charges that were not anticipated by the user.
**Financial Impact:** The user expected all AI costs to be covered by their Claude Max subscription. Instead, the plugin consumed their Anthropic API credits separately, triggering auto-recharge billing.
**Root Cause:** The Claude Agent SDK (`@anthropic-ai/claude-agent-sdk`) automatically discovers and uses `ANTHROPIC_API_KEY` from environment variables or `.env` files. Claude-mem's worker service runs AI operations (observation compression, summaries) through this SDK, which consumes API credits independently of the user's Claude Max subscription.
---
## Problem Analysis
### User Expectations vs. Reality
| Expectation | Reality |
|-------------|---------|
| Claude Max ($100/mo) covers all Claude usage | Claude Max covers Claude Code IDE usage only |
| Plugin enhances Claude Code without extra cost | Plugin uses separate API calls via SDK |
| No API key needed since using Claude Max | SDK auto-discovers `.env` API keys |
| Billing would be transparent | Silent API key discovery leads to surprise charges |
### The Discovery Flow
1. User installs claude-mem plugin via marketplace
2. User has an `ANTHROPIC_API_KEY` in project `.env` file (for other purposes)
3. Plugin worker starts on first Claude Code session
4. Worker spawns Claude Agent SDK for observation processing
5. SDK auto-discovers `ANTHROPIC_API_KEY` from environment
6. Every observation compression and session summary uses API credits
7. User receives unexpected invoice for API usage
---
## Technical Details
### How claude-mem Uses the Claude Agent SDK
Claude-mem uses `@anthropic-ai/claude-agent-sdk` (version ^0.1.76) for AI-powered operations:
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker/SDKAgent.ts`
```typescript
// Line 26
import { query } from '@anthropic-ai/claude-agent-sdk';
// Lines 100-114 - SDK query execution
const queryResult = query({
prompt: messageGenerator,
options: {
model: modelId,
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
disallowedTools,
abortController: session.abortController,
pathToClaudeCodeExecutable: claudePath
}
});
```
### API Key Discovery Chain
The Claude Agent SDK uses a standard discovery mechanism:
1. **Environment Variable:** `process.env.ANTHROPIC_API_KEY`
2. **File Discovery:** `~/.anthropic/api_key` or project `.env` files
3. **Inherited Environment:** Claude Code passes its environment to spawned processes
**From hooks architecture documentation (line 826-828):**
```markdown
### API Key Protection
**Configuration:**
- Anthropic API key in `~/.anthropic/api_key` or `ANTHROPIC_API_KEY` env var
- Worker inherits environment from Claude Code
- Never logged or stored in database
```
### Worker Service Environment Inheritance
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker-service.ts`
```typescript
// Line 263 - Worker spawns with full environment
env: process.env
```
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/infrastructure/ProcessManager.ts`
```typescript
// Line 273 - Process inherits environment
...process.env,
```
This means any `ANTHROPIC_API_KEY` present in the parent process environment or discovered from `.env` files will be used by the worker.
### What Operations Consume API Credits
| Operation | Trigger | API Usage |
|-----------|---------|-----------|
| Observation Compression | PostToolUse hook | ~0.5-2K tokens per observation |
| Session Summary | Summary hook | ~2-5K tokens per session |
| Follow-up Queries | Multi-turn processing | Variable |
**Estimated Usage Per Session:**
- Active coding session: 20-50 tool uses
- At ~1.5K tokens per observation: 30-75K tokens
- Session summary: ~3K tokens
- **Total per session: 33-78K tokens**
### Alternative Providers (Not Using Anthropic API)
Claude-mem supports alternative AI providers that DO NOT use the Anthropic API:
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker/GeminiAgent.ts`
```typescript
// Line 376
const apiKey = settings.CLAUDE_MEM_GEMINI_API_KEY || process.env.GEMINI_API_KEY || '';
```
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker/OpenRouterAgent.ts`
```typescript
// Line 418
const apiKey = settings.CLAUDE_MEM_OPENROUTER_API_KEY || process.env.OPENROUTER_API_KEY || '';
```
These providers require explicit configuration and do not auto-discover.
---
## Impact Assessment
### Financial Impact
| Scenario | Estimated Monthly Cost |
|----------|------------------------|
| Light usage (5 sessions/day) | $10-30 |
| Moderate usage (15 sessions/day) | $30-90 |
| Heavy usage (30+ sessions/day) | $90-200+ |
**Compounding Factors:**
- Auto-recharge enabled by default on Anthropic accounts
- No notification before charges occur
- User may not realize plugin is source of usage
### User Experience Impact
1. **Trust Violation:** Users expect plugins to be transparent about costs
2. **Subscription Confusion:** Claude Max subscription doesn't cover SDK API usage
3. **No Consent:** API key used without explicit opt-in
4. **Discovery Difficulty:** Source of charges not immediately obvious
### Affected User Base
- Users with `ANTHROPIC_API_KEY` in project `.env` files
- Users with API key in `~/.anthropic/api_key`
- Users who exported `ANTHROPIC_API_KEY` for other tools
- Users who don't know they have an API key configured
---
## Root Cause Analysis
### Primary Root Cause
**Silent API key auto-discovery by the Claude Agent SDK without user consent or notification.**
The SDK is designed for developer use cases where explicit API key configuration is expected. When used within a plugin context, the automatic discovery behavior creates a mismatch between user expectations and system behavior.
### Contributing Factors
1. **No Pre-Flight Check:** Plugin doesn't warn users that it will use API credits
2. **No Opt-In Flow:** API key usage happens automatically without consent
3. **No Usage Visibility:** No way to see API consumption before it happens
4. **Documentation Gap:** Not clearly documented that separate API credits are used
5. **Provider Default:** Default provider is 'claude' which uses Anthropic API
### Why This Wasn't Caught Earlier
- Developer testing uses API keys intentionally
- Claude Max subscription model is newer
- Auto-discovery is a feature for SDK users, not plugin users
- No telemetry on API key discovery
---
## Recommended Solutions
### Immediate Fixes (v9.0.1)
#### 1. Add First-Run Warning
Display a prominent warning on first plugin activation:
```
[claude-mem] IMPORTANT: This plugin uses the Claude Agent SDK for AI operations.
If you have an ANTHROPIC_API_KEY configured, it will be used for:
- Observation compression
- Session summaries
This may incur separate API charges beyond your Claude Max subscription.
To avoid charges, configure an alternative provider in ~/.claude-mem/settings.json:
- Set CLAUDE_MEM_PROVIDER to "gemini" or "openrouter"
- Or ensure no ANTHROPIC_API_KEY is accessible to the plugin
Continue? [Y/n]
```
#### 2. Detect and Warn About API Key
Add a check during worker initialization:
```typescript
// Pseudo-code for worker-service.ts
const hasAnthropicKey = !!(
process.env.ANTHROPIC_API_KEY ||
existsSync(join(homedir(), '.anthropic', 'api_key'))
);
if (hasAnthropicKey && provider === 'claude') {
logger.warn('SYSTEM',
'ANTHROPIC_API_KEY detected. Plugin AI operations will consume API credits. ' +
'Configure CLAUDE_MEM_PROVIDER in settings.json to use a free alternative.'
);
}
```
#### 3. Default to Free Provider
Change default provider from 'claude' to 'gemini' (free tier available):
**File:** `src/shared/SettingsDefaultsManager.ts`
```typescript
// Line 66 - Change default
CLAUDE_MEM_PROVIDER: 'gemini', // Changed from 'claude' - free tier by default
```
### Medium-Term Solutions (v9.1.0)
#### 4. Opt-In API Key Usage
Require explicit configuration to use Anthropic API:
```json
// ~/.claude-mem/settings.json
{
"CLAUDE_MEM_PROVIDER": "claude",
"CLAUDE_MEM_ANTHROPIC_API_KEY_CONSENT": true // New required field
}
```
#### 5. Usage Estimation Before Processing
Show estimated token usage before processing:
```
[claude-mem] Processing 25 observations
Estimated API usage: ~37,500 tokens (~$0.15)
Provider: claude (ANTHROPIC_API_KEY)
```
#### 6. Environment Isolation
Prevent automatic API key inheritance:
```typescript
// In worker spawn
env: {
...process.env,
ANTHROPIC_API_KEY: undefined, // Explicitly unset unless opted-in
}
```
### Long-Term Solutions (v10.0.0)
#### 7. Built-In Usage Dashboard
Add API usage tracking to the viewer UI at http://localhost:37777:
- Total tokens consumed this session/day/month
- Estimated costs by provider
- Warning thresholds
#### 8. Provider Configuration Wizard
First-run wizard in viewer UI:
1. "Choose your AI provider for memory operations"
2. Options: Free (Gemini), Pay-per-use (Claude/OpenRouter), Self-hosted
3. Configure API keys through UI, not discovery
---
## Priority/Severity Assessment
### Severity: HIGH
**Rationale:**
- Direct financial impact on users
- Trust violation in plugin ecosystem
- No user consent for charges
- Difficult to discover source of charges
- Affects users who believed Claude Max covered all costs
### Priority: P1 - Critical
**Rationale:**
- Active financial harm to users
- Reputation risk for plugin
- Simple fixes available
- User trust requires immediate action
### Recommended Timeline
| Milestone | Target | Description |
|-----------|--------|-------------|
| Hotfix | 48 hours | Add warning message, update docs |
| v9.0.1 | 1 week | Detection, warning, default provider change |
| v9.1.0 | 2 weeks | Opt-in flow, usage estimation |
| v10.0.0 | 1 month | Full usage dashboard, configuration wizard |
---
## Files to Modify
| File | Change |
|------|--------|
| `src/services/worker-service.ts` | Add API key detection and warning |
| `src/shared/SettingsDefaultsManager.ts` | Change default provider to 'gemini' |
| `plugin/scripts/context-hook.js` | Add first-run warning |
| `docs/public/installation.mdx` | Document API key usage clearly |
| `docs/public/configuration.mdx` | Add provider selection guidance |
| `CHANGELOG.md` | Document the change |
---
## Testing Recommendations
### Test Cases to Add
1. **API Key Detection Test:** Verify warning appears when ANTHROPIC_API_KEY present
2. **Default Provider Test:** Ensure new installs default to gemini
3. **Opt-In Test:** Verify claude provider requires explicit consent
4. **Environment Isolation Test:** Confirm API key not inherited without consent
### Manual Testing
```bash
# Test 1: Clean environment (should default to gemini)
unset ANTHROPIC_API_KEY
claude # Start Claude Code with plugin
# Test 2: With API key (should show warning)
export ANTHROPIC_API_KEY="sk-test-key"
claude # Should display warning
# Test 3: Explicit opt-in
# Configure settings.json with consent flag
claude # Should use claude provider without warning
```
---
## Conclusion
Issue #588 represents a critical UX and financial issue where the plugin's use of the Claude Agent SDK results in unexpected API charges for users who have an `ANTHROPIC_API_KEY` configured. The auto-discovery behavior, while useful for developers, creates a poor user experience for plugin users who expect their Claude Max subscription to cover all costs.
**Immediate Action Required:**
1. Release hotfix with warning message
2. Update documentation to clearly state API usage
3. Change default provider to free tier (gemini)
4. Implement opt-in consent for Anthropic API usage
**The fix is straightforward, but the impact on user trust requires prompt action.**
---
## Appendix: Related Issues and Documentation
| Resource | Description |
|----------|-------------|
| [Claude Agent SDK Docs](https://docs.anthropic.com/claude/docs/agent-sdk) | SDK documentation |
| `docs/public/hooks-architecture.mdx` | Hooks and API key documentation |
| `docs/public/configuration.mdx` | Settings configuration reference |
| Issue #511 | Related: Gemini model support |
| Issue #527 | Related: Provider detection issues |
---
## Appendix: User Communication Template
**Suggested Announcement/Changelog Entry:**
```markdown
## Important Notice for v9.0.1
### API Key Usage Disclosure
Claude-mem uses AI for observation compression and session summaries.
If you have an `ANTHROPIC_API_KEY` configured (in ~/.anthropic/api_key,
environment variables, or project .env files), the plugin will use
Anthropic API credits for these operations.
**This is separate from your Claude Max subscription.**
### Changes in v9.0.1
- **Default provider changed to Gemini** (free tier available)
- **Warning displayed** when ANTHROPIC_API_KEY is detected
- **Opt-in required** to use Anthropic API for plugin operations
### For existing users
If you experienced unexpected charges:
1. Check your provider setting: `~/.claude-mem/settings.json`
2. Set `CLAUDE_MEM_PROVIDER` to `"gemini"` for free operation
3. Or remove/unset `ANTHROPIC_API_KEY` if not needed for other tools
We apologize for any confusion or unexpected charges caused by this behavior.
```

View File

@@ -0,0 +1,411 @@
# Issue #590: Blank Terminal Window Pops Up on Windows When Chroma MCP Server Starts
**Date:** 2026-01-07
**Issue Author:** dwd898
**Severity:** Medium (UX disruption, not a functional failure)
**Status:** OPEN - Root cause confirmed, multiple solutions proposed
---
## 1. Executive Summary
On Windows 11, when claude-mem starts the Chroma MCP server via `uvx`, a blank terminal window (Windows Terminal / PowerShell) appears and does not close automatically. Users must manually close this window each time, which disrupts the workflow.
The root cause is that the MCP SDK's `StdioClientTransport` class does not pass the `windowsHide: true` option to the underlying `child_process.spawn()` call. While the claude-mem codebase attempts to set this option, it has no effect because the MCP SDK ignores it.
This issue affects all Windows users who have ChromaDB vector search enabled (the default configuration).
---
## 2. Problem Analysis
### 2.1 User-Reported Symptoms
- A blank terminal window appears when any action triggers Chroma initialization
- The window shows the `uvx.exe` path but contains no output
- The window remains open until manually closed by the user
- This occurs every time ChromaDB is initialized (typically once per Claude session)
### 2.2 Environment Details
| Component | Value |
|-----------|-------|
| OS | Windows 11 64-bit |
| Terminal | PowerShell 7.6.0-preview.6 |
| claude-mem version | 9.0.0 |
| uvx location | `C:\Users\Dell\AppData\Local\Microsoft\WinGet\Links\uvx.exe` |
| MCP SDK version | ^1.25.1 |
### 2.3 Trigger Conditions
The terminal popup occurs when:
1. Claude Code starts a new session with claude-mem enabled
2. A search query is executed with semantic search enabled
3. The ChromaSync service initializes for the first time in a session
4. Any backfill operation triggers Chroma connection
---
## 3. Technical Details
### 3.1 Affected Code Location
**File:** `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/sync/ChromaSync.ts`
**Lines:** 106-124
```typescript
const transportOptions: any = {
command: 'uvx',
args: [
'--python', pythonVersion,
'chroma-mcp',
'--client-type', 'persistent',
'--data-dir', this.VECTOR_DB_DIR
],
stderr: 'ignore'
};
// CRITICAL: On Windows, try to hide console window to prevent PowerShell popups
// Note: windowsHide may not be supported by MCP SDK's StdioClientTransport
if (isWindows) {
transportOptions.windowsHide = true;
logger.debug('CHROMA_SYNC', 'Windows detected, attempting to hide console window', { project: this.project });
}
this.transport = new StdioClientTransport(transportOptions);
```
### 3.2 Why windowsHide Fails
The `StdioClientTransport` class from `@modelcontextprotocol/sdk` accepts configuration options but does **not** forward `windowsHide` to `child_process.spawn()`. The SDK's transport implementation only uses a subset of spawn options:
- `command` - The executable to run
- `args` - Command line arguments
- `env` - Environment variables (optional)
- `stderr` - Stderr handling mode
The `windowsHide` option is silently ignored because it's not part of the SDK's expected interface.
### 3.3 MCP SDK Transport Architecture
```
ChromaSync.ts
|
v
StdioClientTransport (MCP SDK)
|
v
child_process.spawn() [internal to SDK]
|
v
uvx.exe subprocess
|
v
chroma-mcp Python process
```
The SDK controls the spawn call, so claude-mem cannot directly influence the spawn options.
### 3.4 Comparison with Other Subprocess Calls
Other parts of claude-mem successfully hide Windows console windows because they use `child_process.spawn()` directly:
| Component | File | Uses windowsHide | Works on Windows |
|-----------|------|------------------|------------------|
| ProcessManager | `ProcessManager.ts:271` | Yes (direct spawn) | Yes |
| SDKAgent | `SDKAgent.ts:379` | Yes (direct spawn) | Yes |
| BranchManager | `BranchManager.ts:61,88` | Yes (direct spawn) | Yes |
| shared/paths | `paths.ts:103` | Yes (direct spawn) | Yes |
| ChromaSync | `ChromaSync.ts:120` | Yes (via SDK - ignored) | **No** |
---
## 4. Impact Assessment
### 4.1 Affected Users
- All Windows users with ChromaDB enabled (default)
- Approximately 100% of Windows user base
### 4.2 Severity Breakdown
| Aspect | Impact |
|--------|--------|
| Functionality | No impact - Chroma works correctly |
| UX Disruption | Medium - Requires manual window close |
| Workflow Impact | Low - One-time per session |
| Data Integrity | None |
| Security | None |
### 4.3 Workaround Availability
**Current Workaround:** Users can manually close the terminal window. The Chroma process continues running in the background even after the window is closed.
---
## 5. Root Cause Analysis
### 5.1 Primary Cause
The MCP SDK's `StdioClientTransport` class does not implement support for the `windowsHide` spawn option. This is a limitation in the SDK, not a bug in claude-mem.
### 5.2 SDK Gap Analysis
The MCP SDK (version 1.25.1) provides a transport abstraction layer but does not expose all Node.js spawn options. The `StdioClientTransport` constructor signature accepts:
```typescript
interface StdioClientTransportOptions {
command: string;
args?: string[];
env?: NodeJS.ProcessEnv;
stderr?: 'inherit' | 'pipe' | 'ignore';
}
```
Notable missing options:
- `windowsHide`
- `detached`
- `cwd`
- `shell`
### 5.3 Historical Context
The claude-mem codebase has extensively addressed Windows console popup issues in other areas:
- **December 4, 2025:** Added `windowsHide` parameter to ProcessManager
- **December 17, 2025:** PR #378 standardized `windowsHide: true` across all direct spawn calls
- **Known Issue:** The comment in ChromaSync.ts (line 118) explicitly acknowledges this limitation
---
## 6. Recommended Solutions
### 6.1 Solution 1: PowerShell Wrapper (Recommended Short-Term)
**Approach:** Wrap the `uvx` command in a PowerShell invocation that hides the window.
**Implementation:**
```typescript
const transportOptions: any = {
command: 'powershell',
args: [
'-WindowStyle', 'Hidden',
'-Command',
`uvx --python ${pythonVersion} chroma-mcp --client-type persistent --data-dir '${this.VECTOR_DB_DIR}'`
],
stderr: 'ignore'
};
```
**Pros:**
- No SDK changes required
- Immediate fix possible
- Pattern already used in worker-cli.js (lines 1-19)
**Cons:**
- Adds PowerShell dependency (already required for Windows)
- Slightly more complex command construction
- PATH escaping considerations
**Estimated Effort:** 2-4 hours
### 6.2 Solution 2: Custom Transport Layer
**Approach:** Bypass `StdioClientTransport` and implement a custom transport using `child_process.spawn()` directly.
**Implementation:**
```typescript
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { spawn, ChildProcess } from 'child_process';
class WindowsHiddenStdioTransport implements Transport {
private process: ChildProcess;
constructor(options: TransportOptions) {
this.process = spawn(options.command, options.args, {
windowsHide: true,
stdio: ['pipe', 'pipe', options.stderr === 'ignore' ? 'ignore' : 'pipe']
});
}
// ... implement Transport interface
}
```
**Pros:**
- Full control over spawn options
- Clean, maintainable solution
- Reusable for other MCP clients
**Cons:**
- Requires implementing Transport interface
- Must handle stdin/stdout piping manually
- More complex error handling
**Estimated Effort:** 8-16 hours
### 6.3 Solution 3: Upstream SDK Enhancement
**Approach:** Request the MCP SDK team to add `windowsHide` support to `StdioClientTransport`.
**Implementation:**
1. Open issue on MCP SDK repository
2. Propose API extension: `spawnOptions?: Partial<SpawnOptions>`
3. Provide PR if accepted
**Pros:**
- Fixes the root cause
- Benefits all MCP SDK users on Windows
- No workarounds needed
**Cons:**
- Depends on external team
- Uncertain timeline
- May require SDK version bump
**Estimated Effort:** Variable (depends on upstream response)
### 6.4 Solution 4: VBS Wrapper Script
**Approach:** Use a Windows Script Host (VBS) file to launch the process silently.
**Implementation:**
Create `launch-chroma.vbs`:
```vbs
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "uvx --python 3.13 chroma-mcp --client-type persistent --data-dir " & DataDir, 0, False
```
**Pros:**
- Guaranteed hidden window
- Works on all Windows versions
**Cons:**
- Requires additional script file
- Complex path handling
- VBS is deprecated technology
**Estimated Effort:** 4-6 hours
---
## 7. Priority/Severity Assessment
### 7.1 Severity Matrix
| Factor | Rating | Justification |
|--------|--------|---------------|
| User Impact | Medium | Annoying but not blocking |
| Frequency | Low | Once per session |
| Workaround | Yes | Close window manually |
| Data Risk | None | No data loss or corruption |
| Security Risk | None | No security implications |
### 7.2 Recommended Priority
**Priority: P2 (Medium)**
This issue should be addressed in the next minor release but is not urgent enough to warrant an immediate patch release.
### 7.3 Recommendation
Implement **Solution 1 (PowerShell Wrapper)** as an immediate fix for the next release. Simultaneously, open an upstream issue for **Solution 3** to address the root cause in the MCP SDK.
---
## 8. Related Issues and Context
### 8.1 Related GitHub Issues
| Issue | Title | Relationship |
|-------|-------|--------------|
| #367 | Console windows appearing during hook execution | Similar root cause |
| #517 | PowerShell `$_` escaping in Git Bash | Windows shell escaping |
| #555 | Windows hooks IPC issues | Windows platform challenges |
### 8.2 Related PRs
| PR | Title | Relevance |
|----|-------|-----------|
| #378 | Windows stabilization | Added windowsHide to other spawn calls |
| #372 | Worker wrapper architecture | Similar Windows console hiding approach |
### 8.3 Documentation
- Windows Woes Report: `/docs/reports/2026-01-06--windows-woes-comprehensive-report.md`
- Windows Troubleshooting: https://docs.claude-mem.ai/troubleshooting/windows-issues
---
## 9. Testing Recommendations
### 9.1 Test Cases
1. **Basic functionality:** Verify Chroma starts correctly with proposed fix
2. **Window visibility:** Confirm no terminal window appears
3. **Process lifecycle:** Ensure Chroma process terminates on worker shutdown
4. **Error handling:** Verify errors are properly captured despite hidden window
5. **PATH variations:** Test with uvx in different PATH locations
### 9.2 Test Environments
- Windows 11 with PowerShell 7.x
- Windows 11 with PowerShell 5.1
- Windows 10 with PowerShell 5.1
- Windows with Git Bash as default shell
---
## 10. Appendix
### 10.1 Current ChromaSync Connection Flow
```
1. ChromaSync.ensureConnection() called
2. Check if already connected
3. Load Python version from settings
4. Detect Windows platform
5. Set windowsHide: true (ineffective)
6. Create StdioClientTransport with uvx command
7. Connect MCP client to transport
-> POPUP APPEARS HERE
8. Mark as connected
```
### 10.2 PowerShell Command Pattern (from worker-cli.js)
The existing pattern for hidden PowerShell execution:
```typescript
const cmd = `Start-Process -FilePath '${escapedPath}' -ArgumentList '${args}' -WindowStyle Hidden`;
spawnSync("powershell", ["-Command", cmd], {
stdio: "pipe",
timeout: 10000,
windowsHide: true
});
```
### 10.3 MCP SDK Source Reference
The StdioClientTransport implementation in `@modelcontextprotocol/sdk` uses:
```typescript
this._process = spawn(command, args, {
env: this._env,
stdio: ['pipe', 'pipe', stderr]
});
```
Note the absence of `windowsHide` in the spawn options.
---
## 11. Revision History
| Date | Author | Changes |
|------|--------|---------|
| 2026-01-07 | Claude Opus 4.5 | Initial report |

View File

@@ -0,0 +1,423 @@
# Issue #591: OpenRouter Agent Fails to Capture memorySessionId for Empty Prompt History Sessions
**Report Date:** 2026-01-07
**Issue:** [#591](https://github.com/thedotmack/claude-mem/issues/591)
**Reporter:** cjdrilke
**Environment:** claude-mem 9.0.0, Provider: openrouter, Model: xiaomi/mimo-v2-flash:free, Platform: linux
---
## 1. Executive Summary
This issue describes a critical failure in the OpenRouter agent where it cannot store observations for sessions that have an empty prompt history (`prompt_counter = 0`). The error message "Cannot store observations: memorySessionId not yet captured" indicates that the `memorySessionId` is `null` when `processAgentResponse()` attempts to store observations.
**Key Finding:** Unlike the Claude SDK Agent which captures `memorySessionId` from SDK response messages, the OpenRouter Agent has **no mechanism to capture or generate a memorySessionId**. This is a fundamental architectural gap that causes all OpenRouter sessions to fail on their first observation.
**Severity:** Critical
**Priority:** P1
**Impact:** All new OpenRouter sessions fail to store observations
---
## 2. Problem Analysis
### 2.1 Error Manifestation
```
Error: Cannot store observations: memorySessionId not yet captured
```
This error originates from `ResponseProcessor.ts` line 73-75:
```typescript
// CRITICAL: Must use memorySessionId (not contentSessionId) for FK constraint
if (!session.memorySessionId) {
throw new Error('Cannot store observations: memorySessionId not yet captured');
}
```
### 2.2 Affected Code Path
1. OpenRouter session starts via `OpenRouterAgent.startSession()`
2. Session is initialized with `memorySessionId: null`
3. OpenRouter API is queried and returns a response
4. `processAgentResponse()` is called with the response
5. **memorySessionId is still null** - no capture mechanism exists
6. Error thrown, observations not stored
### 2.3 Comparison with SDK Agent
The Claude SDK Agent successfully captures `memorySessionId` at `SDKAgent.ts` lines 120-141:
```typescript
// Capture memory session ID from first SDK message (any type has session_id)
if (!session.memorySessionId && message.session_id) {
session.memorySessionId = message.session_id;
// Persist to database for cross-restart recovery
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
message.session_id
);
// ... verification logging ...
}
```
**The OpenRouter Agent has no equivalent capture mechanism.**
---
## 3. Technical Details
### 3.1 Session ID Architecture
Claude-mem uses a dual session ID system (documented in `docs/SESSION_ID_ARCHITECTURE.md`):
| ID | Purpose | Source |
|----|---------|--------|
| `contentSessionId` | User's Claude Code conversation ID | Hook system |
| `memorySessionId` | Memory agent's internal session for resume | SDK response |
### 3.2 Session Initialization Flow
```
1. Hook creates session
createSDKSession(contentSessionId, project, prompt)
Database state:
├─ content_session_id: "user-session-123"
└─ memory_session_id: NULL (not yet captured)
2. SessionManager.initializeSession() creates ActiveSession:
session = {
sessionDbId: number,
contentSessionId: "user-session-123",
memorySessionId: null, // ← Critical: starts as null
...
}
```
### 3.3 OpenRouter Response Format
OpenRouter uses an OpenAI-compatible API response format:
```typescript
interface OpenRouterResponse {
choices?: Array<{
message?: {
role?: string;
content?: string;
};
finish_reason?: string;
}>;
usage?: {
prompt_tokens?: number;
completion_tokens?: number;
total_tokens?: number;
};
error?: {
message?: string;
code?: string;
};
}
```
**Critical Gap:** This response format does NOT include a `session_id` field. OpenRouter is a stateless API that does not maintain server-side session state.
### 3.4 Root Cause in OpenRouterAgent.ts
In `OpenRouterAgent.startSession()` (lines 85-133), the init response is processed:
```typescript
const initResponse = await this.queryOpenRouterMultiTurn(session.conversationHistory, apiKey, model, siteUrl, appName);
if (initResponse.content) {
// Add response to conversation history
session.conversationHistory.push({ role: 'assistant', content: initResponse.content });
// ... token tracking ...
// Process response using shared ResponseProcessor (no original timestamp for init - not from queue)
await processAgentResponse(
initResponse.content,
session, // ← memorySessionId is still null here
this.dbManager,
this.sessionManager,
worker,
tokensUsed,
null,
'OpenRouter',
undefined
);
}
```
**No memorySessionId capture occurs between session initialization and calling `processAgentResponse()`.**
---
## 4. Impact Assessment
### 4.1 Direct Impact
- **All OpenRouter sessions fail** when `prompt_counter = 0` (new sessions)
- No observations are stored for OpenRouter-based memory extraction
- Error prevents any memory from being captured via OpenRouter
### 4.2 Scope of Impact
| Affected | Not Affected |
|----------|--------------|
| All OpenRouter providers | Claude SDK Agent |
| All OpenRouter models | Gemini Agent (if implemented differently) |
| New sessions (prompt_counter = 0) | Potentially resumed sessions* |
*Note: Resumed sessions may work if they were previously processed by Claude SDK and have a captured `memorySessionId` from a fallback.
### 4.3 User Experience
Users configuring OpenRouter as their provider will:
1. See successful API calls to OpenRouter
2. Receive no stored observations
3. See error messages in logs about memorySessionId not captured
4. Have an empty memory database despite apparent processing
---
## 5. Root Cause Analysis
### 5.1 Primary Root Cause
**The OpenRouter Agent was implemented without a mechanism to generate or capture `memorySessionId`.**
Unlike the Claude SDK which returns a `session_id` in its response messages, OpenRouter's OpenAI-compatible API is stateless and does not provide session identifiers.
### 5.2 Contributing Factors
1. **Architectural Mismatch**: The `memorySessionId` concept was designed around the Claude SDK's session management, which OpenRouter does not have.
2. **Missing Initialization Logic**: Neither the OpenRouter agent nor the ResponseProcessor generates a `memorySessionId` when one is not provided by the API.
3. **Shared ResponseProcessor Assumption**: `ResponseProcessor.ts` assumes `memorySessionId` is always captured before it is called, which is true for Claude SDK but not for OpenRouter.
### 5.3 Why It Worked Before (Speculation)
This may have been masked if:
- OpenRouter fallback to Claude SDK triggered before the bug manifested
- Initial testing used existing sessions with previously captured `memorySessionId`
- The feature was added without comprehensive test coverage for new sessions
---
## 6. Recommended Solutions
### 6.1 Solution A: Generate memorySessionId for OpenRouter (Recommended)
Since OpenRouter is stateless, generate a unique `memorySessionId` when starting an OpenRouter session:
**Location:** `OpenRouterAgent.ts` in `startSession()` method, after session initialization
```typescript
async startSession(session: ActiveSession, worker?: WorkerRef): Promise<void> {
try {
// Generate memorySessionId for stateless providers (OpenRouter doesn't have session tracking)
if (!session.memorySessionId) {
const generatedMemorySessionId = `openrouter-${session.contentSessionId}-${Date.now()}`;
session.memorySessionId = generatedMemorySessionId;
// Persist to database
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
generatedMemorySessionId
);
logger.info('SESSION', `MEMORY_ID_GENERATED | sessionDbId=${session.sessionDbId} | memorySessionId=${generatedMemorySessionId} | provider=OpenRouter`, {
sessionId: session.sessionDbId,
memorySessionId: generatedMemorySessionId
});
}
// ... rest of existing code ...
}
}
```
**Pros:**
- Minimal code changes
- Follows existing patterns
- Works with stateless APIs
- Maintains FK integrity
**Cons:**
- Memory session ID format differs from Claude SDK
- No resume capability (OpenRouter is stateless anyway)
### 6.2 Solution B: Use contentSessionId as memorySessionId for Stateless Providers
For stateless providers, use the `contentSessionId` directly as the `memorySessionId`:
```typescript
if (!session.memorySessionId) {
session.memorySessionId = session.contentSessionId;
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
session.contentSessionId
);
}
```
**Pros:**
- Simpler approach
- No additional ID generation
**Cons:**
- Violates the architectural principle that memorySessionId should differ from contentSessionId
- Could cause issues with session isolation (see SESSION_ID_ARCHITECTURE.md warnings)
### 6.3 Solution C: Allow null memorySessionId with Auto-Generation in ResponseProcessor
Modify `ResponseProcessor.ts` to generate a `memorySessionId` if one is not present:
```typescript
// In processAgentResponse():
if (!session.memorySessionId) {
const generatedId = `auto-${session.contentSessionId}-${Date.now()}`;
session.memorySessionId = generatedId;
// Persist to database
dbManager.getSessionStore().updateMemorySessionId(session.sessionDbId, generatedId);
logger.info('DB', `AUTO_GENERATED_MEMORY_ID | sessionDbId=${session.sessionDbId} | memorySessionId=${generatedId}`);
}
```
**Pros:**
- Works for any agent type
- Single point of fix
**Cons:**
- ResponseProcessor takes on responsibilities it shouldn't have
- Less explicit about provider behavior
### 6.4 Recommended Approach
**Solution A** is recommended because:
1. It explicitly handles the stateless nature of OpenRouter
2. It follows the existing pattern established by Claude SDK Agent
3. It keeps the memorySessionId generation in the agent where provider-specific logic belongs
4. It maintains clear separation of concerns
---
## 7. Priority/Severity Assessment
### 7.1 Severity Matrix
| Factor | Assessment |
|--------|------------|
| **Data Loss** | High - All observations lost for OpenRouter sessions |
| **Functionality** | Complete - OpenRouter provider is non-functional |
| **Workaround** | Exists - Use Claude SDK or Gemini providers |
| **Affected Users** | Subset - Only OpenRouter users |
| **Regression** | Unknown - May be present since OpenRouter was added |
### 7.2 Priority Assignment
**Priority: P1 (High)**
Rationale:
- Complete feature failure for affected configuration
- Users who choose OpenRouter are completely blocked
- Fix is straightforward with low regression risk
### 7.3 Recommended Timeline
| Action | Timeline |
|--------|----------|
| Hotfix development | 1-2 hours |
| Testing | 1 hour |
| Code review | 30 minutes |
| Release | Same day |
---
## 8. Testing Recommendations
### 8.1 Unit Tests to Add
```typescript
// tests/worker/openrouter-agent.test.ts
describe('OpenRouterAgent memorySessionId handling', () => {
it('should generate memorySessionId when session has none', async () => {
const session = createMockSession({
memorySessionId: null,
contentSessionId: 'test-content-123'
});
await openRouterAgent.startSession(session, mockWorker);
expect(session.memorySessionId).not.toBeNull();
expect(session.memorySessionId).toContain('openrouter-');
});
it('should persist generated memorySessionId to database', async () => {
const session = createMockSession({ memorySessionId: null });
await openRouterAgent.startSession(session, mockWorker);
expect(mockDbManager.getSessionStore().updateMemorySessionId)
.toHaveBeenCalledWith(session.sessionDbId, expect.any(String));
});
it('should not regenerate memorySessionId if already present', async () => {
const existingId = 'existing-memory-id';
const session = createMockSession({ memorySessionId: existingId });
await openRouterAgent.startSession(session, mockWorker);
expect(session.memorySessionId).toBe(existingId);
});
});
```
### 8.2 Integration Tests to Add
```typescript
describe('OpenRouter end-to-end observation storage', () => {
it('should successfully store observations for new OpenRouter sessions', async () => {
// Create new session via hook
const sessionDbId = createSDKSession(db, 'content-123', 'test-project', 'test prompt');
// Initialize and start OpenRouter agent
const session = sessionManager.initializeSession(sessionDbId);
await openRouterAgent.startSession(session, mockWorker);
// Verify observations were stored
const observations = db.prepare('SELECT * FROM observations WHERE memory_session_id = ?')
.all(session.memorySessionId);
expect(observations.length).toBeGreaterThan(0);
});
});
```
---
## 9. Related Files
| File | Relevance |
|------|-----------|
| `src/services/worker/OpenRouterAgent.ts` | Primary fix location |
| `src/services/worker/agents/ResponseProcessor.ts` | Error origin (line 73-75) |
| `src/services/worker/SessionManager.ts` | Session initialization |
| `src/services/worker/SDKAgent.ts` | Reference implementation for memorySessionId capture |
| `src/services/sqlite/sessions/create.ts` | Database session creation |
| `docs/SESSION_ID_ARCHITECTURE.md` | Architecture documentation |
| `tests/worker/agents/response-processor.test.ts` | Existing test coverage |
---
## 10. Conclusion
Issue #591 is a critical bug that renders the OpenRouter provider non-functional for new sessions. The root cause is a missing `memorySessionId` capture mechanism specific to stateless providers like OpenRouter.
The recommended fix is to generate a unique `memorySessionId` in `OpenRouterAgent.startSession()` before calling `processAgentResponse()`. This fix is straightforward, follows existing patterns, and carries low regression risk.
**Immediate Action Required:** Implement Solution A and release a hotfix.

View File

@@ -0,0 +1,417 @@
# Issue #596: ProcessTransport is not ready for writing - Generator aborted on every observation
**Date:** 2026-01-07
**Issue:** [#596](https://github.com/thedotmack/claude-mem/issues/596)
**Reported by:** soho-dev-account
**Severity:** Critical
**Status:** Under Investigation
**Labels:** bug
---
## 1. Executive Summary
After a clean install of claude-mem v9.0.0, the SDK agent aborts every observation with a "ProcessTransport is not ready for writing" error. The worker starts successfully and the HTTP API responds, but no observations are stored to the database. The error originates from the Claude Agent SDK's internal transport layer, specifically in the bundled `worker-service.cjs` at line 1119.
**Key Finding:** This is a race condition or timing issue in the Claude Agent SDK's ProcessTransport initialization. The SDK attempts to write messages to its subprocess transport before the transport's ready state is established.
**Impact:** Complete loss of memory functionality. The system appears operational but silently fails to capture any development context.
---
## 2. Problem Analysis
### 2.1 Symptoms
1. **Worker starts successfully** - No startup errors, HTTP endpoints respond
2. **Observations are queued** - HTTP 200 responses from `/api/sessions/observations`
3. **Generator aborts immediately** - Every queued message triggers generator abort
4. **No observations stored** - Database remains empty despite active usage
### 2.2 Error Signature
```
error: ProcessTransport is not ready for writing at write (/Users/.../worker-service.cjs:1119:5337)
```
### 2.3 Worker Logs Pattern
```
[INFO ] [SDK ] Starting SDK query...
[INFO ] [SDK ] Creating message generator...
[INFO ] [SESSION] [session-3458] Generator aborted
```
The log shows:
- SDK query starts (line 78-85 in SDKAgent.ts)
- Message generator created (line 266-272 in SDKAgent.ts)
- Generator aborts immediately (line 169 in SessionRoutes.ts)
The gap between "Creating message generator" and "Generator aborted" indicates the SDK's `query()` function throws before yielding any messages.
### 2.4 Environment Context
- **OS:** macOS 26.3, Apple Silicon
- **Bun:** 1.3.5
- **Node:** v22.21.1
- **Claude Code:** 2.0.75
- **claude-mem:** v9.0.0 (clean install)
---
## 3. Technical Details
### 3.1 ProcessTransport in the Agent SDK
The `ProcessTransport` class is part of the Claude Agent SDK (`@anthropic-ai/claude-agent-sdk`), bundled into `worker-service.cjs` during the build process. This transport manages bidirectional IPC communication between:
1. **Parent process:** The claude-mem worker service
2. **Child process:** Claude Code subprocess spawned for SDK queries
The transport uses stdin/stdout pipes to exchange JSON messages with the Claude Code process.
### 3.2 The Ready State Problem
ProcessTransport maintains a `ready` state that gates write operations:
```javascript
// Approximate structure from bundled code
class ProcessTransport {
ready = false;
write(data) {
if (!this.ready) {
throw new Error("ProcessTransport is not ready for writing");
}
// ... actual write to subprocess stdin
}
async start() {
// Spawn subprocess
// Set up pipes
this.ready = true;
}
}
```
The error occurs when `write()` is called before `start()` completes, or when the transport initialization fails silently.
### 3.3 Code Flow Analysis
1. **Session initialization** (`SessionRoutes.ts:237-299`)
- HTTP request creates/fetches session
- Calls `startGeneratorWithProvider()`
2. **Generator startup** (`SessionRoutes.ts:118-217`)
- Sets `session.currentProvider`
- Calls `agent.startSession(session, worker)`
- Wraps in Promise with error/finally handlers
3. **SDK query invocation** (`SDKAgent.ts:102-114`)
```typescript
const queryResult = query({
prompt: messageGenerator,
options: {
model: modelId,
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
disallowedTools,
abortController: session.abortController,
pathToClaudeCodeExecutable: claudePath
}
});
```
4. **SDK internal flow** (inside `query()`)
- Creates ProcessTransport
- Spawns Claude subprocess
- **RACE:** Attempts to write before ready
### 3.4 Abort Controller Signal Path
When ProcessTransport throws, the error propagates through:
1. `query()` async iterator throws
2. `for await` loop in `startSession()` exits
3. Generator promise rejects
4. SessionRoutes `.catch()` handler executes
5. Checks `session.abortController.signal.aborted`
6. Since not manually aborted, logs "Generator failed" at ERROR level
7. `.finally()` handler executes
8. Logs "Generator aborted" (misleading - it wasn't aborted, it crashed)
---
## 4. Impact Assessment
### 4.1 Functional Impact
| Component | Status | Notes |
|-----------|--------|-------|
| Worker startup | Working | HTTP server binds correctly |
| HTTP API | Working | Endpoints respond with 200 |
| Session creation | Working | Database rows created |
| Observation queueing | Working | Messages added to pending queue |
| SDK query | **Failing** | ProcessTransport error |
| Observation storage | **Failing** | No observations saved |
| Summary generation | **Failing** | Depends on working SDK |
| CLAUDE.md generation | **Partial** | No recent activity to show |
### 4.2 User Impact
- **100% loss of memory functionality** - No observations captured
- **Silent failure mode** - Worker appears healthy
- **Queue grows indefinitely** - Messages stuck in "processing"
- **No error visible to user** - Requires checking worker logs
### 4.3 System Recovery
After this failure:
1. Pending messages remain in database (crash-safe design)
2. On worker restart, messages are recoverable
3. If SDK issue is resolved, backlog will process
---
## 5. Root Cause Analysis
### 5.1 Primary Hypothesis: SDK Version Incompatibility
**Confidence: 85%**
The Claude Agent SDK version (`^0.1.76`) may have introduced changes to ProcessTransport initialization timing that conflict with how claude-mem invokes `query()`.
Evidence:
- v9.0.0 works for some users but fails for others
- Error occurs in SDK internals, not claude-mem code
- Similar timing issues seen in previous SDK versions
### 5.2 Alternative Hypothesis: Subprocess Spawn Race
**Confidence: 70%**
The Claude Code subprocess may fail to start or respond in time, causing the transport to remain in non-ready state.
Evidence:
- `pathToClaudeCodeExecutable` is auto-detected
- Different Claude Code versions may have different startup times
- Apple Silicon Bun may spawn processes differently
### 5.3 Alternative Hypothesis: Bun-Specific IPC Issue
**Confidence: 50%**
Bun's process spawning may handle stdin/stdout pipes differently than Node.js, causing transport initialization to fail.
Evidence:
- claude-mem runs under Bun
- Agent SDK may not be tested extensively with Bun runtime
- Bun 1.3.5 is relatively new
### 5.4 Related: Recent Version Mismatch Fix (#567)
Commit `e22e2bfc` fixed a version mismatch causing infinite worker restart loops. This touched:
- `plugin/package.json`
- `plugin/scripts/worker-service.cjs`
- Hook scripts
While this fix addressed restart loops, it may have introduced timing changes that expose this race condition.
---
## 6. Recommended Solutions
### 6.1 Immediate Workarounds
#### Option A: Retry with Backoff (Quick Fix)
Add retry logic around `query()` invocation:
```typescript
// SDKAgent.ts - wrap query() with retry
async function queryWithRetry(options: QueryOptions, maxRetries = 3): Promise<QueryResult> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return query(options);
} catch (error) {
if (error.message?.includes('ProcessTransport is not ready') && attempt < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, 100 * (attempt + 1)));
continue;
}
throw error;
}
}
}
```
**Pros:** Quick to implement, may resolve timing-sensitive cases
**Cons:** Masks underlying issue, adds latency
#### Option B: Verify Claude Executable Before Query
Add explicit verification that Claude is responsive:
```typescript
// Before calling query()
const testResult = execSync(`${claudePath} --version`, { timeout: 5000 });
if (!testResult) {
throw new Error('Claude executable not responding');
}
```
**Pros:** Catches subprocess spawn failures early
**Cons:** Adds startup latency, doesn't address transport race
### 6.2 Medium-Term Fixes
#### Option C: Pin SDK Version
Lock to a known-working SDK version:
```json
{
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "0.1.75"
}
}
```
**Pros:** Immediate resolution if regression confirmed
**Cons:** Misses security updates, may not match Claude Code version
#### Option D: Add Transport Ready Callback
Request SDK feature to expose transport ready state:
```typescript
// Hypothetical API
const queryResult = query({
prompt: messageGenerator,
options: { ... },
onTransportReady: () => logger.info('SDK', 'Transport ready')
});
```
**Pros:** Proper fix at SDK level
**Cons:** Requires SDK changes
### 6.3 Long-Term Solutions
#### Option E: V2 SDK Migration
The V2 SDK (`unstable_v2_createSession`) uses a different session-based architecture that may not have this race condition:
```typescript
await using session = unstable_v2_createSession({
model: 'claude-sonnet-4-5-20250929'
});
await session.send(initPrompt); // Explicit send/receive
for await (const msg of session.receive()) { ... }
```
**Pros:** Modern API, explicit lifecycle control
**Cons:** V2 is "unstable preview", requires significant refactor
#### Option F: Alternative Agent Provider
Use Gemini or OpenRouter as default when SDK fails:
```typescript
// SessionRoutes.ts - fallback logic
try {
await sdkAgent.startSession(session, worker);
} catch (error) {
if (error.message?.includes('ProcessTransport')) {
logger.warn('SESSION', 'SDK transport failed, falling back to Gemini');
await geminiAgent.startSession(session, worker);
}
}
```
**Pros:** System remains functional
**Cons:** Different model behavior, requires API key
---
## 7. Priority/Severity Assessment
### 7.1 Severity: Critical
| Criterion | Rating | Justification |
|-----------|--------|---------------|
| Functional Impact | Critical | Core feature completely broken |
| User Count | Unknown | Appears on clean installs |
| Data Loss | Low | No data corrupted, queue preserved |
| Recoverability | Medium | Worker restart may help |
| Workaround Available | Limited | Use alternative provider |
### 7.2 Priority: P0
This should be treated as a P0 (highest priority) issue because:
1. **Core functionality broken** - Memory capture is the primary feature
2. **Silent failure** - Users may not realize observations aren't being saved
3. **Clean install affected** - New users cannot use the product
4. **No easy workaround** - Requires code changes or provider switching
### 7.3 Recommended Action Plan
1. **Immediate (Day 1)**
- [ ] Reproduce issue in controlled environment
- [ ] Test with pinned SDK version 0.1.75
- [ ] Test with Node.js instead of Bun
- [ ] Add explicit error message to SessionRoutes for this failure mode
2. **Short-term (Week 1)**
- [ ] Implement retry logic (Option A)
- [ ] Add transport failure telemetry
- [ ] Document workaround in issue comments
- [ ] File SDK issue with Anthropic if confirmed regression
3. **Medium-term (Week 2-4)**
- [ ] Evaluate V2 SDK migration timeline
- [ ] Add graceful fallback to alternative providers
- [ ] Improve generator error visibility in viewer UI
---
## 8. Appendix
### 8.1 Related Files
| File | Relevance |
|------|-----------|
| `src/services/worker/SDKAgent.ts` | SDK query invocation |
| `src/services/worker/http/routes/SessionRoutes.ts` | Generator lifecycle management |
| `src/services/worker/SessionManager.ts` | Session state and queue management |
| `src/services/worker-types.ts` | ActiveSession type definition |
| `plugin/scripts/worker-service.cjs` | Bundled worker with SDK code |
### 8.2 Related Issues
- **#567** - Version mismatch causing infinite worker restart loop (may be related)
- **#520** - Stuck messages analysis (similar symptom pattern)
- **#532** - Memory leak analysis (generator lifecycle issues)
### 8.3 Related Documentation
- `docs/context/agent-sdk-v2-preview.md` - V2 SDK documentation
- `docs/context/agent-sdk-v2-examples.ts` - V2 SDK code examples
- `docs/reports/2026-01-02--generator-failure-investigation.md` - Previous generator failure analysis
### 8.4 Test Commands
```bash
# Check worker logs
tail -f ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log
# Check pending queue
npm run queue
# Restart worker
npm run worker:restart
# Test with specific SDK version
npm install @anthropic-ai/claude-agent-sdk@0.1.75
npm run build-and-sync
```
---
**Report prepared by:** Claude Code
**Analysis date:** 2026-01-07
**Next review:** After reproduction attempt

View File

@@ -0,0 +1,271 @@
# Issue #597: Too Many Bugs - Technical Analysis Report
**Date:** 2026-01-07
**Issue:** [#597](https://github.com/thedotmack/claude-mem/issues/597)
**Author:** TullyMonster
**Labels:** bug
**Status:** Open
---
## 1. Executive Summary
Issue #597 is a bug report from user TullyMonster containing four screenshots documenting various issues encountered over a two-day period. The report lacks textual description of the specific bugs, relying entirely on visual evidence. The user apologizes for the delay in reporting, stating the bugs significantly hampered their productivity.
**Key Limitation:** This analysis is constrained by the image-only nature of the report. The four screenshots (with dimensions 2560x1239, 1511x628, 2560x3585, and 1907x1109 pixels) cannot be programmatically analyzed to extract specific error messages or UI states.
**Community Confirmation:** Another user (ham-zax) commented agreeing with the severity: "yeah atleast make beta testing, it hampers productivity"
---
## 2. Problem Analysis
### 2.1 Contextual Analysis
Based on the timing (January 7, 2026), the user was running claude-mem v9.0.0, which was released on January 5, 2026. This version introduced the "Live Context System with Distributed CLAUDE.md Generation" (PR #556), a significant architectural change.
The same user (TullyMonster) also commented on Issue #596 with "same as you," indicating they experienced the ProcessTransport error that causes all observations to fail silently.
### 2.2 Related Issues Filed Same Day
| Issue | Title | Relevance |
|-------|-------|-----------|
| #596 | ProcessTransport is not ready for writing - Generator aborted | User confirmed experiencing this |
| #598 | Too many messages, polluting conversation history | UX issue with plugin messages |
| #602 | PostToolUse Error: worker-service.cjs failed to start | Worker startup failures on Windows |
### 2.3 Screenshot Analysis (Inferred)
Based on screenshot dimensions and the pattern of issues being reported on v9.0.0:
| Screenshot | Dimensions | Likely Content |
|------------|------------|----------------|
| Image 1 | 2560x1239 | Full-screen terminal/IDE showing errors |
| Image 2 | 1511x628 | Error message dialog or log output |
| Image 3 | 2560x3585 | Very tall - likely scrolling log output or multiple stacked errors |
| Image 4 | 1907x1109 | Terminal or UI showing bug manifestation |
---
## 3. Technical Details
### 3.1 Probable Bug Categories (v9.0.0)
Based on the cluster of issues around this time, the bugs likely fall into these categories:
#### A. ProcessTransport Failures (High Probability)
```
error: ProcessTransport is not ready for writing
at write (/Users/.../worker-service.cjs:1119:5337)
at streamInput (/Users/.../worker-service.cjs:1122:1041)
```
- Every observation fails with "Generator aborted"
- Queue depth accumulates (87+ unprocessed items)
- Worker UI works, but no observations are stored
#### B. Worker Startup Failures (Moderate Probability)
```
[ERROR] [HOOK] save-hook failed Worker did not become ready within 15 seconds. (port 37777)
[ERROR] [SYSTEM] Worker failed to start (health check timeout)
[ERROR] [SYSTEM] Failed to start server. Is port 37777 in use?
```
#### C. Session/Memory Issues (Moderate Probability)
```
[ERROR] Cannot store observations: memorySessionId not yet captured
[WARN] Generator exited unexpectedly
```
#### D. Conversation Pollution (Possible)
Multiple "Hello memory agent" messages appearing in conversation history, disrupting workflow.
### 3.2 Environment Assumptions
Based on the user's participation in Issue #596 (macOS focus) and screenshot dimensions:
- **OS:** Likely macOS (high-resolution display)
- **Version:** v9.0.0 (released Jan 5, 2026)
- **Runtime:** Bun 1.3.x
---
## 4. Impact Assessment
### 4.1 User Impact
| Impact Area | Severity | Description |
|-------------|----------|-------------|
| Productivity | **Critical** | User spent 2 days dealing with bugs instead of coding |
| Data Loss | **High** | Observations not being stored (ProcessTransport issue) |
| Workflow Disruption | **High** | Multiple bugs compounding the problem |
| User Trust | **Medium** | User apologizes for delay, showing frustration |
### 4.2 Broader Impact
The community response indicates this is not an isolated incident:
- ham-zax: "yeah atleast make beta testing, it hampers productivity"
- Multiple users on #596: "same as you", "same 3"
This suggests v9.0.0 has significant stability issues affecting multiple users.
---
## 5. Root Cause Analysis
### 5.1 Likely Root Causes
#### Primary: ProcessTransport Race Condition
The Claude Agent SDK's ProcessTransport class attempts to write to stdin before the spawned process is ready. This is a timing/race condition that manifests inconsistently.
**Evidence:**
- Clean installs affected
- Both Bun 1.3.4 and 1.3.5 affected
- Prompts ARE recorded correctly, only SDK agent fails
#### Secondary: Version 9.0.0 Regression
PR #556 introduced significant changes to the Live Context System, which may have:
1. Introduced new race conditions
2. Affected worker lifecycle management
3. Changed timing of critical initialization steps
#### Tertiary: Platform-Specific Issues
Windows users experiencing additional problems:
- `wmic` command not recognized (newer Windows versions)
- Port binding conflicts
- PowerShell variable escaping in Git Bash
### 5.2 Contributing Factors
| Factor | Description |
|--------|-------------|
| Rapid releases | v8.5.10 to v9.0.0 in 2 days |
| Complex architecture | 5 lifecycle hooks, async worker, SDK integration |
| Limited beta testing | Community comment suggests need for beta channel |
| Platform diversity | macOS, Windows, Linux all have different issues |
---
## 6. Recommended Solutions
### 6.1 Immediate Actions (For User)
1. **Request Clarification** - Post a comment asking:
```
@TullyMonster Thank you for the detailed screenshots! To help us
investigate these issues more effectively, could you please provide:
1. Which specific errors/behaviors are shown in each screenshot?
2. Your environment (OS, claude-mem version, Bun version)?
3. Relevant log entries from ~/.claude-mem/logs/worker-YYYY-MM-DD.log?
4. Steps to reproduce any of these issues?
We've identified several related issues (#596, #598, #602) and want to
ensure we're addressing your specific problems.
```
2. **Verify Version** - Confirm user is on v9.0.0
3. **Link Related Issues** - Cross-reference with:
- #596 (ProcessTransport)
- #598 (message pollution)
- #602 (worker startup)
### 6.2 Technical Fixes (For Maintainers)
| Priority | Fix | Issue |
|----------|-----|-------|
| P0 | Fix ProcessTransport race condition | #596 |
| P1 | Improve worker startup reliability | #602 |
| P2 | Reduce conversation pollution | #598 |
| P3 | Add better error recovery | General |
### 6.3 Process Improvements
1. **Beta Channel** - Consider a beta release channel for major versions
2. **Automated Testing** - Expand CI to catch lifecycle issues
3. **Error Reporting** - Add structured error logging that's easier to share
4. **Bug Report Template** - Update template to encourage log submission
---
## 7. Priority/Severity Assessment
### 7.1 Individual Issue Severity
| Aspect | Rating | Justification |
|--------|--------|---------------|
| Frequency | High | Multiple users affected |
| Impact | Critical | Complete workflow disruption |
| Urgency | High | Blocking user productivity |
| Complexity | Medium | Root causes identified in related issues |
### 7.2 Overall Priority
**Priority: P1 - High**
**Rationale:**
- User lost 2 days of productivity
- Multiple corroborating reports from community
- v9.0.0 appears to have introduced regressions
- Plugin is actively harming user experience rather than helping
### 7.3 Recommended Triage
1. **Consolidate** - This issue likely duplicates #596, #602, and/or #598
2. **Request Details** - Ask user to specify which screenshots map to which issues
3. **Consider Rollback** - If issues persist, consider advising users to downgrade to v8.5.10
4. **Hotfix** - Prioritize a v9.0.1 release addressing ProcessTransport issue
---
## 8. Appendix
### 8.1 Related Issues Timeline
| Date | Issue | Event |
|------|-------|-------|
| Jan 5 | - | v9.0.0 released |
| Jan 6 | #571 | "Cannot store observations" |
| Jan 6 | #573 | "bun does not auto install" |
| Jan 7 01:10 | #588 | API key cost warning |
| Jan 7 10:17 | #596 | ProcessTransport failures |
| Jan 7 13:09 | #597 | This issue |
| Jan 7 14:08 | #598 | Conversation pollution |
| Jan 7 18:13 | #602 | Worker startup failures |
### 8.2 Screenshot Metadata
| # | Dimensions | Aspect Ratio | Notes |
|---|------------|--------------|-------|
| 1 | 2560x1239 | 2.07:1 | Wide monitor screenshot |
| 2 | 1511x628 | 2.41:1 | Cropped dialog/window |
| 3 | 2560x3585 | 0.71:1 | Tall scrolling capture |
| 4 | 1907x1109 | 1.72:1 | Standard window capture |
### 8.3 Version History
| Version | Date | Notable Changes |
|---------|------|-----------------|
| v8.5.10 | Jan 5 | Pre-v9 stable |
| v9.0.0 | Jan 5 | Live Context System (PR #556) |
| v9.0.0+ | Jan 7 | Version mismatch fix (PR #567) |
---
## 9. Conclusion
Issue #597 represents user frustration with multiple bugs encountered in claude-mem v9.0.0. While the image-only report makes specific diagnosis difficult, contextual analysis strongly suggests the user experienced:
1. ProcessTransport failures causing observation loss (#596)
2. Possibly worker startup issues (#602)
3. Possibly conversation pollution (#598)
**Recommended Next Steps:**
1. Request additional details from the user
2. Link this issue to #596 as likely duplicate/related
3. Prioritize v9.0.1 hotfix for ProcessTransport issue
4. Consider implementing a beta testing channel for major releases
---
*Report generated: 2026-01-07*
*Analysis based on: GitHub issue data, related issues, commit history, and contextual inference*

View File

@@ -0,0 +1,365 @@
# Issue #598: Conversation History Pollution - Technical Analysis Report
**Issue:** Too many messages, polluting my conversation history
**Author:** abhijit8ganguly-afk
**Created:** 2026-01-07
**Labels:** bug
**Report Date:** 2026-01-07
---
## 1. Executive Summary
Users are experiencing conversation history pollution when using `/resume` in Claude Code. Plugin-generated messages starting with "Hello memory agent" appear in the user's conversation history, making it difficult to resume sessions. This issue stems from a fundamental architectural concern: the Claude Agent SDK's resume mechanism appears to inject messages into the user's transcript when the `resume` parameter is passed with the user's `contentSessionId` instead of the plugin's separate `memorySessionId`.
**Key Finding:** The plugin maintains two separate session IDs for isolation:
- `contentSessionId`: The user's Claude Code session (what appears in `/resume`)
- `memorySessionId`: The plugin's internal SDK session (should NEVER appear in user's history)
When these become conflated, plugin messages pollute the user's conversation history.
---
## 2. Problem Analysis
### 2.1 User-Reported Symptoms
When using `/resume`, users see multiple messages starting with "Hello memory agent" appearing in their conversation history. These messages are internal to the claude-mem plugin and should be invisible to users.
### 2.2 Source of "Hello memory agent" Messages
The message originates from the mode configuration file at `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/plugin/modes/code.json`:
```json
{
"prompts": {
"continuation_greeting": "Hello memory agent, you are continuing to observe the primary Claude session.",
"continuation_instruction": "IMPORTANT: Continue generating observations from tool use messages using the XML structure below."
}
}
```
This greeting is injected via `buildContinuationPrompt()` in `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/sdk/prompts.ts`:
```typescript
export function buildContinuationPrompt(userPrompt: string, promptNumber: number, contentSessionId: string, mode: ModeConfig): string {
return `${mode.prompts.continuation_greeting}
...
```
### 2.3 When These Messages Appear
The continuation prompt is used when `session.lastPromptNumber > 1` (any prompt after the initial session start). This is controlled in `SDKAgent.ts`:
```typescript
const initPrompt = isInitPrompt
? buildInitPrompt(session.project, session.contentSessionId, session.userPrompt, mode)
: buildContinuationPrompt(session.userPrompt, session.lastPromptNumber, session.contentSessionId, mode);
```
---
## 3. Technical Details
### 3.1 Session ID Architecture
The plugin uses a dual session ID system to maintain isolation between user conversations and plugin operations:
| Session ID | Purpose | Storage | Should Appear in /resume |
|------------|---------|---------|--------------------------|
| `contentSessionId` | User's Claude Code session | From hook context | Yes - this IS the user's session |
| `memorySessionId` | Plugin's internal SDK session | Captured from SDK responses | **NEVER** |
**Critical Code Comments from `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/sqlite/SessionStore.ts`:**
```typescript
// NOTE: memory_session_id starts as NULL. It is captured by SDKAgent from the first SDK
// response and stored via updateMemorySessionId(). CRITICAL: memory_session_id must NEVER
// equal contentSessionId - that would inject memory messages into the user's transcript!
```
### 3.2 SDK Query Flow
The `SDKAgent.startSession()` method at `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker/SDKAgent.ts` controls how the plugin interacts with Claude:
```typescript
const queryResult = query({
prompt: messageGenerator,
options: {
model: modelId,
// Only resume if BOTH: (1) we have a memorySessionId AND (2) this isn't the first prompt
// On worker restart, memorySessionId may exist from a previous SDK session but we
// need to start fresh since the SDK context was lost
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
disallowedTools,
abortController: session.abortController,
pathToClaudeCodeExecutable: claudePath
}
});
```
**Key Point:** The `resume` parameter specifies which session to continue. If this accidentally uses `contentSessionId`, messages appear in the user's history.
### 3.3 Message Generator Architecture
The `createMessageGenerator()` method yields synthetic user messages to the SDK:
```typescript
yield {
type: 'user',
message: {
role: 'user',
content: initPrompt // Contains "Hello memory agent" for continuation prompts
},
session_id: session.contentSessionId, // References user's session for context
parent_tool_use_id: null,
isSynthetic: true // Marked as synthetic - should not appear in real history
};
```
### 3.4 Transcript Storage Locations
Claude Code stores conversation transcripts at:
```
~/.claude/projects/{dashed-cwd}/{session_id}.jsonl
```
If the wrong session ID is used, plugin messages get written to the user's transcript file.
---
## 4. Impact Assessment
### 4.1 User Experience Impact
| Severity | Description |
|----------|-------------|
| High | Users cannot effectively use `/resume` due to pollution |
| Medium | Confusion about what messages are "real" vs plugin-generated |
| Low | Increased scrolling/navigation effort |
### 4.2 Functional Impact
- **Session Resume Degraded:** The core `/resume` functionality becomes less useful
- **Context Window Pollution:** Plugin messages consume valuable context window tokens
- **Trust Erosion:** Users may question if the plugin is behaving correctly
### 4.3 Affected Users
All users who:
1. Have claude-mem plugin installed
2. Use `/resume` to continue sessions
3. Have multi-turn conversations where continuation prompts are generated
---
## 5. Root Cause Analysis
### 5.1 Primary Root Cause
The issue likely occurs when the session ID passed to the SDK's `resume` parameter conflates with the user's session. This could happen in several scenarios:
**Scenario A: Stale Session ID Resume (Previously Identified)**
When the worker restarts with a stale `memorySessionId` from a previous session, it may attempt to resume into a non-existent session. The fix at `SDKAgent.ts:109` prevents this:
```typescript
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
```
However, if this logic was not working correctly, or if there was a race condition, the wrong ID could be used.
**Scenario B: Session ID Capture Timing**
The `memorySessionId` is captured from the first SDK response:
```typescript
if (!session.memorySessionId && message.session_id) {
session.memorySessionId = message.session_id;
// Persist to database for cross-restart recovery
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
message.session_id
);
}
```
If this capture fails or is delayed, subsequent messages might use the wrong session context.
**Scenario C: Message Yielding with User Session Context**
The message generator yields messages with `session_id: session.contentSessionId`:
```typescript
yield {
type: 'user',
message: { role: 'user', content: initPrompt },
session_id: session.contentSessionId, // <-- This is the user's session ID!
...
};
```
This field may be used by the SDK to determine where to persist messages. If so, this is a design issue where the plugin's internal messages reference the user's session.
### 5.2 Contributing Factors
1. **Shared Conversation History:** The plugin maintains a `conversationHistory` array that includes plugin messages, used for provider switching (Claude/Gemini/OpenRouter). This history may leak into user-visible contexts.
2. **Continuation Prompt Content:** The "Hello memory agent" greeting is explicitly designed to be internal but has no technical mechanism preventing it from appearing in user transcripts.
3. **Synthetic Message Flag:** Messages are marked `isSynthetic: true` but this flag may not be respected by all downstream components.
---
## 6. Recommended Solutions
### 6.1 Immediate Mitigations
#### Option A: Remove or Minimize Continuation Greeting (Low Effort)
Modify the mode configuration to use a less intrusive greeting:
```json
{
"continuation_greeting": "", // Empty or very minimal
}
```
**Pros:** Quick fix, no code changes
**Cons:** Doesn't fix the underlying session ID issue
#### Option B: Verify Session ID Isolation (Medium Effort)
Add runtime validation to ensure `memorySessionId` never equals `contentSessionId`:
```typescript
if (session.memorySessionId === session.contentSessionId) {
logger.error('SESSION', 'CRITICAL: memorySessionId matches contentSessionId - messages will pollute user history!', {
contentSessionId: session.contentSessionId,
memorySessionId: session.memorySessionId
});
// Reset memorySessionId to force fresh SDK session
session.memorySessionId = null;
}
```
### 6.2 Structural Fixes
#### Option C: Remove session_id from Yielded Messages (High Effort)
Investigate if the `session_id` field in yielded messages can be omitted or changed:
```typescript
yield {
type: 'user',
message: { role: 'user', content: initPrompt },
// session_id: session.contentSessionId, // REMOVE or use memorySessionId
parent_tool_use_id: null,
isSynthetic: true
};
```
**Requires:** Understanding of SDK internals and testing
#### Option D: Separate Transcript Storage (High Effort)
Ensure plugin messages are stored in a completely separate transcript path:
- User transcript: `~/.claude/projects/{cwd}/{contentSessionId}.jsonl`
- Plugin transcript: `~/.claude-mem/transcripts/{memorySessionId}.jsonl`
### 6.3 Long-Term Architecture
#### Option E: Agent SDK Isolation Mode
Request or implement an SDK feature that marks certain messages as "agent-internal" and prevents them from appearing in user-facing `/resume` history.
---
## 7. Priority/Severity Assessment
| Dimension | Rating | Justification |
|-----------|--------|---------------|
| **User Impact** | High | Directly affects core user workflow (`/resume`) |
| **Frequency** | High | Affects all users with continuation prompts |
| **Workaround Available** | Partial | Users can ignore messages, but UX degraded |
| **Fix Complexity** | Medium-High | Requires understanding SDK session mechanics |
### Recommended Priority: P1 (High)
This issue should be addressed promptly as it:
1. Degrades a core Claude Code feature (`/resume`)
2. Affects all plugin users
3. May indicate a deeper session isolation problem
4. Could lead to users disabling the plugin
---
## 8. Related Issues and Documentation
### Related Issues
- Previous fix for stale session resume: `.claude/plans/fix-stale-session-resume-crash.md`
- Session ID architecture: `SESSION_ID_ARCHITECTURE.md` (referenced in plans)
### Key Files for Investigation
| File | Relevance |
|------|-----------|
| `src/services/worker/SDKAgent.ts` | SDK query loop and session handling |
| `src/sdk/prompts.ts` | Prompt generation including "Hello memory agent" |
| `plugin/modes/code.json` | Mode configuration with greeting text |
| `src/services/sqlite/SessionStore.ts` | Session ID storage and validation |
| `tests/sdk-agent-resume.test.ts` | Test file for resume logic |
### Test Coverage
The resume parameter logic has unit tests at `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/tests/sdk-agent-resume.test.ts` covering:
- INIT prompt scenarios (should NOT resume)
- Continuation prompt scenarios (should resume with memorySessionId)
- Edge cases (empty/undefined memorySessionId)
- Stale session crash prevention
---
## 9. Appendix: Code References
### A. Continuation Greeting in Mode Config
**File:** `plugin/modes/code.json`
```json
"continuation_greeting": "Hello memory agent, you are continuing to observe the primary Claude session."
```
### B. Prompt Building
**File:** `src/sdk/prompts.ts:174-177`
```typescript
export function buildContinuationPrompt(...): string {
return `${mode.prompts.continuation_greeting}
...
```
### C. Message Yielding
**File:** `src/services/worker/SDKAgent.ts:283-292`
```typescript
yield {
type: 'user',
message: { role: 'user', content: initPrompt },
session_id: session.contentSessionId,
parent_tool_use_id: null,
isSynthetic: true
};
```
### D. Session ID Capture
**File:** `src/services/worker/SDKAgent.ts:120-140`
```typescript
if (!session.memorySessionId && message.session_id) {
session.memorySessionId = message.session_id;
this.dbManager.getSessionStore().updateMemorySessionId(
session.sessionDbId,
message.session_id
);
...
}
```
---
*Report generated: 2026-01-07*
*Analysis based on codebase at commit: 687146ce (merge main)*

View File

@@ -0,0 +1,323 @@
# Technical Report: Issue #599 - Windows Drive Root 400 Error
**Issue:** [#599](https://github.com/thedotmack/claude-mem/issues/599)
**Title:** user-message-hook.js fails with 400 error when running from Windows drive root (C:\)
**Author:** PakAbhishek
**Created:** 2026-01-07
**Severity:** Low
**Priority:** Medium
**Component:** Hooks / Session Initialization
---
## 1. Executive Summary
When running Claude Code from a Windows drive root directory (e.g., `C:\`), the `user-message-hook.js` script fails with a 400 HTTP error during session startup. The root cause is that `path.basename('C:\')` returns an empty string on Windows, which causes the API call to `/api/context/inject?project=` to fail with the error "Project(s) parameter is required".
**Key Findings:**
- The bug is **cosmetic only** - all core memory functionality continues to work correctly
- A robust fix already exists in `src/utils/project-name.ts` (`getProjectName()` function) but is not used by `user-message-hook.ts`
- The fix requires updating `user-message-hook.ts` to use the existing `getProjectName()` utility instead of raw `path.basename()`
- The `context-hook.ts` is already immune to this bug because it uses `getProjectContext()` which wraps `getProjectName()`
**Affected Files:**
- `src/hooks/user-message-hook.ts` (needs fix)
- `plugin/scripts/user-message-hook.js` (built artifact, auto-fixed by rebuild)
---
## 2. Problem Analysis
### 2.1 User-Reported Symptoms
1. Error message on Claude Code startup when cwd is `C:\`:
```
error: Failed to fetch context: 400
at C:\Users\achau\.claude\plugins\cache\thedotmack\claude-mem\9.0.0\scripts\user-message-hook.js:19:1339
```
2. The error appears during the SessionStart hook phase
3. Despite the error, all other functionality works correctly:
- Worker health check: passing
- MCP tools: connected and functional
- Memory search: working
- Session observations: saved correctly
### 2.2 Reproduction Steps
1. Open terminal on Windows
2. Navigate to drive root: `cd C:\`
3. Start Claude Code: `claude`
4. Observe the startup error
### 2.3 Environment
- **OS:** Windows 11
- **claude-mem version:** 9.0.0
- **Bun version:** 1.3.5
- **Claude Code:** Latest
---
## 3. Technical Details
### 3.1 Code Flow Analysis
The `user-message-hook.ts` extracts the project name using:
```typescript
// File: src/hooks/user-message-hook.ts (lines 18-23)
const project = basename(process.cwd());
const response = await fetch(
`http://127.0.0.1:${port}/api/context/inject?project=${encodeURIComponent(project)}&colors=true`,
{ method: 'GET' }
);
```
When `process.cwd()` returns `C:\`, the `path.basename()` function returns an empty string:
```javascript
> require('path').basename('C:\\')
''
```
This results in an API call to:
```
/api/context/inject?project=&colors=true
```
### 3.2 Server-Side Validation
The `/api/context/inject` endpoint in `SearchRoutes.ts` performs strict validation:
```typescript
// File: src/services/worker/http/routes/SearchRoutes.ts (lines 207-223)
private handleContextInject = this.wrapHandler(async (req: Request, res: Response): Promise<void> => {
const projectsParam = (req.query.projects as string) || (req.query.project as string);
const useColors = req.query.colors === 'true';
if (!projectsParam) {
this.badRequest(res, 'Project(s) parameter is required');
return;
}
const projects = projectsParam.split(',').map(p => p.trim()).filter(Boolean);
if (projects.length === 0) {
this.badRequest(res, 'At least one project is required');
return;
}
// ...
});
```
The validation correctly rejects empty project names, returning HTTP 400.
### 3.3 Existing Solution
A robust solution already exists in `src/utils/project-name.ts`:
```typescript
// File: src/utils/project-name.ts (lines 12-40)
export function getProjectName(cwd: string | null | undefined): string {
if (!cwd || cwd.trim() === '') {
logger.warn('PROJECT_NAME', 'Empty cwd provided, using fallback', { cwd });
return 'unknown-project';
}
const basename = path.basename(cwd);
// Edge case: Drive roots on Windows (C:\, J:\) or Unix root (/)
// path.basename('C:\') returns '' (empty string)
if (basename === '') {
const isWindows = process.platform === 'win32';
if (isWindows) {
const driveMatch = cwd.match(/^([A-Z]):\\/i);
if (driveMatch) {
const driveLetter = driveMatch[1].toUpperCase();
const projectName = `drive-${driveLetter}`;
logger.info('PROJECT_NAME', 'Drive root detected', { cwd, projectName });
return projectName;
}
}
logger.warn('PROJECT_NAME', 'Root directory detected, using fallback', { cwd });
return 'unknown-project';
}
return basename;
}
```
This function:
- Handles null/undefined cwd
- Handles empty basename (drive roots)
- Returns meaningful names like `drive-C`, `drive-D` for Windows drive roots
- Returns `unknown-project` for Unix root or other edge cases
### 3.4 Comparison: Fixed vs. Unfixed Hooks
| Hook | Implementation | Status |
|------|---------------|--------|
| `context-hook.ts` | Uses `getProjectContext()` which calls `getProjectName()` | Immune to bug |
| `user-message-hook.ts` | Uses raw `basename(process.cwd())` | **Vulnerable** |
| `new-hook.ts` | Receives `cwd` from stdin, uses `getProjectName()` | Immune to bug |
| `save-hook.ts` | Uses basename but receives cwd from API context | Context-dependent |
---
## 4. Impact Assessment
### 4.1 Severity: Low
- **Functional Impact:** Cosmetic only - the error message is displayed but does not affect core functionality
- **Data Integrity:** No data loss or corruption
- **Workaround Available:** Yes - run Claude from a project directory instead of drive root
### 4.2 Affected Users
- Users running Claude Code from Windows drive roots (C:\, D:\, etc.)
- Estimated as a small percentage of users based on typical usage patterns
- More likely to affect users doing quick tests or troubleshooting
### 4.3 User Experience Impact
- Confusing error message on startup
- Users may incorrectly believe the plugin is broken
- Error appears in stderr alongside legitimate context information
---
## 5. Root Cause Analysis
### 5.1 Primary Cause
The `user-message-hook.ts` was implemented using a direct `path.basename()` call instead of the standardized `getProjectName()` utility function that handles edge cases.
### 5.2 Contributing Factors
1. **Inconsistent Pattern Usage:** Different hooks use different approaches to extract project names
2. **Missing Validation:** No client-side validation of project name before making API call
3. **Edge Case Not Tested:** Windows drive root is an unusual but valid working directory
### 5.3 Historical Context
The `getProjectName()` utility was added to handle this exact edge case (see `src/utils/project-name.ts`), but not all hooks were updated to use it. The `context-hook.ts` uses the newer `getProjectContext()` function, while `user-message-hook.ts` still uses the older pattern.
---
## 6. Recommended Solutions
### 6.1 Primary Fix (Recommended)
Update `user-message-hook.ts` to use the existing `getProjectName()` utility:
```typescript
// Current (vulnerable):
import { basename } from "path";
const project = basename(process.cwd());
// Fixed:
import { getProjectName } from "../utils/project-name.js";
const project = getProjectName(process.cwd());
```
**Benefits:**
- Uses battle-tested utility
- Consistent with other hooks
- Handles all edge cases (drive roots, Unix root, empty cwd)
- Provides meaningful project names (`drive-C`) instead of fallbacks
### 6.2 Alternative: Inline Fix (User-Suggested)
The user suggested an inline fix in the issue:
```javascript
let projectName = basename(process.cwd());
if (!projectName || projectName === '') {
const cwd = process.cwd();
projectName = cwd.match(/^([A-Za-z]:)[\\/]?$/)
? `drive-${cwd[0].toUpperCase()}`
: 'unknown-project';
}
```
**Evaluation:**
- Functionally correct
- Duplicates existing logic in `getProjectName()`
- Does not address the pattern inconsistency
- Acceptable if import constraints prevent using the utility
### 6.3 Additional Improvements (Optional)
1. **Add Client-Side Validation:**
```typescript
if (!project || project.trim() === '') {
throw new Error('Unable to determine project name from working directory');
}
```
2. **Standardize All Hooks:** Audit other hooks using `basename(process.cwd())` and update to use `getProjectName()`
3. **Add Unit Tests:** Create tests for `user-message-hook.ts` covering:
- Normal project directories
- Windows drive roots (C:\, D:\)
- Unix root (/)
- Trailing slashes
---
## 7. Priority and Severity Assessment
### 7.1 Classification
| Metric | Value | Justification |
|--------|-------|---------------|
| **Severity** | Low | Cosmetic error only, no functional impact |
| **Priority** | Medium | User-facing error, easy fix, affects Windows users |
| **Effort** | Trivial | Single line change + rebuild |
| **Risk** | Very Low | Using existing, tested utility function |
### 7.2 Recommendation
**Recommended Action:** Fix in next patch release (9.0.1)
**Rationale:**
- Simple fix with minimal risk
- Improves Windows user experience
- Demonstrates responsiveness to community feedback
- Pattern already exists in codebase
### 7.3 Testing Requirements
1. Verify fix on Windows with `C:\` as cwd
2. Verify existing behavior unchanged for normal project directories
3. Verify worktree detection still works correctly
4. Run full hook test suite
---
## 8. Appendix
### 8.1 Related Files
| File | Purpose | Fix Required |
|------|---------|--------------|
| `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/hooks/user-message-hook.ts` | Source hook (needs fix) | Yes |
| `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/plugin/scripts/user-message-hook.js` | Built hook | Auto-rebuilds |
| `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/utils/project-name.ts` | Utility (has fix) | No |
| `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/hooks/context-hook.ts` | Reference implementation | No |
| `/Users/alexnewman/conductor/workspaces/claude-mem/budapest/src/services/worker/http/routes/SearchRoutes.ts` | API validation | No |
### 8.2 Related Issues
- Windows compatibility has been a focus area, with 56+ memory entries documenting Windows-specific fixes
- This issue follows the pattern of other Windows edge case bugs
### 8.3 References
- [Node.js path.basename documentation](https://nodejs.org/api/path.html#pathbasenamepath-suffix)
- [Windows file system path formats](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file)

View File

@@ -0,0 +1,432 @@
# Issue #600: Documentation Audit - Features Documented But Not Implemented
**Report Date:** 2026-01-07
**Issue Author:** @bguidolim
**Issue Created:** 2026-01-07
**Status:** Open
**Priority:** Medium-High
---
## 1. Executive Summary
A comprehensive audit by @bguidolim has identified **8 discrepancies** between the claude-mem documentation (`docs/public/`) and the actual implementation in the main branch. The core issue is that documentation describes beta-branch features as if they exist in the production release, leading to user confusion and failed feature expectations.
### Key Findings
| Category | Issue | Severity |
|----------|-------|----------|
| **Critical** | Version Channel UI missing from frontend | High |
| **Critical** | Endless Mode settings not validated/functional | High |
| **Moderate** | Troubleshoot Skill referenced but doesn't exist | Medium |
| **Moderate** | Folder CLAUDE.md setting documented but always enabled | Medium |
| **Moderate** | Skills directory documented but replaced by MCP | Medium |
| **Minor** | Allowed branches list incomplete | Low |
| **Minor** | Hook count inconsistency (5 vs 6) | Low |
| **Minor** | MCP tool count clarification needed | Low |
### Recommendation
Implement **Option B** (documentation update) for most items, with selective **Option A** (feature completion) for Version Channel UI given its near-complete backend implementation.
---
## 2. Problem Analysis
### 2.1 Documentation-Reality Gap
The documentation at `docs/public/` describes several features that:
1. Exist only in beta branches (`beta/endless-mode`, `beta/7.0`)
2. Have partial implementations (backend only, no frontend)
3. Were removed during architecture migrations (MCP transition)
4. Have non-functional settings (documented but ignored in code)
### 2.2 Impact on Users
Users following the documentation will:
- Look for UI elements that don't exist (Version Channel switcher)
- Configure settings that have no effect (Endless Mode, Folder CLAUDE.md)
- Invoke skills that don't exist (troubleshoot skill)
- Expect directory structures that don't match reality
---
## 3. Technical Details
### 3.1 Version Channel UI (High Severity)
**Documentation Claims** (`docs/public/beta-features.mdx`):
- Lines 14-24 describe a Version Channel switcher in the Settings modal
- Users should see "Settings gear icon" > "Version Channel" section
- Options include "Try Beta (Endless Mode)" and "Switch to Stable"
**Actual Implementation**:
| Component | Status | Location |
|-----------|--------|----------|
| `BranchManager.ts` | Implemented | `src/services/worker/BranchManager.ts` |
| `getBranchInfo()` | Implemented | Backend API |
| `switchBranch()` | Implemented | Backend API |
| `pullUpdates()` | Implemented | Backend API |
| `/api/branch/status` | Implemented | `SettingsRoutes.ts:169-172` |
| `/api/branch/switch` | Implemented | `SettingsRoutes.ts:178-209` |
| `/api/branch/update` | Implemented | `SettingsRoutes.ts:214-228` |
| **UI Component** | **NOT IMPLEMENTED** | `ContextSettingsModal.tsx` has no Version Channel section |
**Verification** (from `ContextSettingsModal.tsx`):
The component contains sections for:
- Loading settings (observations, sessions)
- Filters (types, concepts)
- Display settings
- Advanced settings (provider, model, port)
There is **no Version Channel section**. A grep for "Version Channel", "version channel", or "channel" in `src/ui/` returns no results.
**Related Issues**: #333, #436, #461 (all closed without merging UI)
---
### 3.2 Endless Mode Settings (High Severity)
**Documentation Claims** (`docs/public/endless-mode.mdx`):
```json
{
"CLAUDE_MEM_ENDLESS_MODE": "false",
"CLAUDE_MEM_ENDLESS_WAIT_TIMEOUT_MS": "90000"
}
```
**Actual Implementation**:
The `SettingsRoutes.ts` file (lines 87-124) defines the validated `settingKeys` array:
```typescript
const settingKeys = [
'CLAUDE_MEM_MODEL',
'CLAUDE_MEM_CONTEXT_OBSERVATIONS',
'CLAUDE_MEM_WORKER_PORT',
'CLAUDE_MEM_WORKER_HOST',
'CLAUDE_MEM_PROVIDER',
'CLAUDE_MEM_GEMINI_API_KEY',
// ... 20+ other settings
'CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE',
];
```
**Neither `CLAUDE_MEM_ENDLESS_MODE` nor `CLAUDE_MEM_ENDLESS_WAIT_TIMEOUT_MS` are present in this array.**
A grep for `ENDLESS_MODE` in `src/` returns only CLAUDE.md context files (auto-generated), not any TypeScript implementation.
**Current Location**: Implementation exists only in `upstream/beta/endless-mode` branch.
**Related Issues**: #366, #403, #416 (all closed, feature still in beta only)
---
### 3.3 Troubleshoot Skill (Medium Severity)
**Documentation Claims**:
`docs/public/troubleshooting.mdx` (lines 8-20):
```markdown
## Quick Diagnostic Tool
Describe any issues you're experiencing to Claude, and the troubleshoot skill
will automatically activate to provide diagnosis and fixes.
The troubleshoot skill will:
- Check worker status and health
- Verify database existence and integrity
- ...
```
`docs/public/architecture/overview.mdx` (lines 165-175):
```
plugin/skills/
├── mem-search/
├── troubleshoot/ ← Documented but doesn't exist
│ ├── SKILL.md
│ └── operations/
└── version-bump/
```
**Actual Implementation**:
```bash
$ ls plugin/skills/
ls: plugin/skills/: No such file or directory
```
The `plugin/skills/` directory **does not exist** in the main branch.
**Historical Context**: Skills were merged in PR #72 (v5.2) but later removed during the MCP migration. The documentation was not updated to reflect this architectural change.
---
### 3.4 Folder CLAUDE.md Setting (Medium Severity)
**Documentation Claims** (`docs/public/configuration.mdx`, lines 232-238):
| Setting | Default | Description |
|---------|---------|-------------|
| `CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED` | `false` | Enable auto-generation of folder CLAUDE.md files |
**Actual Implementation**:
In `ResponseProcessor.ts` (lines 216-233), folder CLAUDE.md updates are triggered unconditionally:
```typescript
// Update folder CLAUDE.md files for touched folders (fire-and-forget)
const allFilePaths: string[] = [];
for (const obs of observations) {
allFilePaths.push(...(obs.files_modified || []));
allFilePaths.push(...(obs.files_read || []));
}
if (allFilePaths.length > 0) {
updateFolderClaudeMdFiles(
allFilePaths,
session.project,
getWorkerPort(),
projectRoot
).catch(error => {
logger.warn('FOLDER_INDEX', 'CLAUDE.md update failed (non-critical)', ...);
});
}
```
**The setting `CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED` is never read.** The feature runs unconditionally when files are touched.
Additionally, the setting is not in the `SettingsRoutes.ts` settingKeys array, so it cannot be configured through the API.
**Fix in Progress**: PR #589
---
### 3.5 Skills Directory (Medium Severity)
**Documentation Claims** (`docs/public/architecture/overview.mdx`, lines 165-175):
```
plugin/skills/
├── mem-search/
│ ├── SKILL.md
│ ├── operations/
│ └── principles/
├── troubleshoot/
└── version-bump/
```
**Actual Implementation**:
The `plugin/skills/` directory does not exist. Search functionality is now provided by MCP tools defined in `src/servers/mcp-server.ts`:
```typescript
const tools = [
{ name: '__IMPORTANT', ... },
{ name: 'search', ... },
{ name: 'timeline', ... },
{ name: 'get_observations', ... }
];
```
The skill-based architecture was replaced by MCP tools during the v6.x architecture evolution. The documentation still describes the old skill-based system.
---
### 3.6 Allowed Branches List (Low Severity)
**Location**: `SettingsRoutes.ts:187`
```typescript
const allowedBranches = ['main', 'beta/7.0', 'feature/bun-executable'];
```
**Issue**: Missing `beta/endless-mode` which exists in upstream and is documented.
---
### 3.7 Hook Count Inconsistency (Low Severity)
| Source | Stated Count |
|--------|--------------|
| `docs/public/architecture/overview.mdx` | "6 lifecycle hooks" |
| Root `CLAUDE.md` | "5 Lifecycle Hooks" |
| Actual `hooks.json` | 4 hook types (SessionStart, UserPromptSubmit, PostToolUse, Stop) |
**Actual Hooks** (from `plugin/hooks/hooks.json`):
1. SessionStart (with smart-install, worker-service, context-hook, user-message-hook)
2. UserPromptSubmit (with worker-service, new-hook)
3. PostToolUse (with worker-service, save-hook)
4. Stop (with worker-service, summary-hook)
Note: The documentation may be counting individual script invocations rather than hook types.
---
### 3.8 MCP Tool Count (Low Severity)
**Documentation Claims**: "4 MCP tools"
**Actual Tools**:
1. `__IMPORTANT` - Instructional/workflow guidance (not a functional tool)
2. `search` - Search memory index
3. `timeline` - Get chronological context
4. `get_observations` - Fetch full observation details
The claim is technically correct, but `__IMPORTANT` is workflow documentation rather than a functional tool.
---
## 4. Impact Assessment
### 4.1 User Experience Impact
| Issue | User Impact | Frequency |
|-------|-------------|-----------|
| Version Channel UI | Users cannot switch branches via UI | High - Documented prominently |
| Endless Mode | Config has no effect | Medium - Beta feature |
| Troubleshoot Skill | Skill invocation fails | High - Troubleshooting entry point |
| Folder CLAUDE.md | Setting ignored | Low - Niche feature |
| Skills Directory | Structure doesn't match | Low - Developer documentation |
### 4.2 Developer Experience Impact
| Issue | Developer Impact |
|-------|------------------|
| Architecture docs outdated | New contributors confused by skill references |
| Hook count mismatch | Onboarding confusion |
| API endpoint gaps | Integration developers encounter missing features |
---
## 5. Root Cause Analysis
### 5.1 Primary Causes
1. **Branch Divergence**: Beta branches contain features that were documented but never merged to main
2. **Architecture Migration**: The MCP transition removed the skill system but docs weren't updated
3. **Documentation-First Development**: Features were documented during planning but implementation was incomplete
4. **Missing Sync Process**: No automated check between docs and code
### 5.2 Contributing Factors
1. **Multiple Authors**: Documentation and code written by different contributors
2. **Long-Running Branches**: Beta branches existed for extended periods
3. **Incomplete PRs**: Related issues (#333, #436, #461, #366, #403, #416) were closed without merging
---
## 6. Recommended Solutions
### 6.1 Immediate Actions (This Week)
| Item | Action | Owner | Effort |
|------|--------|-------|--------|
| Troubleshoot Skill | Remove references from `troubleshooting.mdx` | Docs | 1 hour |
| Skills Directory | Update `overview.mdx` to show current MCP architecture | Docs | 2 hours |
| Hook Count | Align all sources to "5 hooks" | Docs | 30 min |
| MCP Tool Clarification | Note that `__IMPORTANT` is workflow guidance | Docs | 15 min |
### 6.2 Short-Term Actions (This Sprint)
| Item | Action | Owner | Effort |
|------|--------|-------|--------|
| Endless Mode | Add "Beta Only" badge to `endless-mode.mdx` and `beta-features.mdx` | Docs | 1 hour |
| Version Channel | Add "Beta Only" badge OR complete UI implementation | Eng/Docs | 2-8 hours |
| Folder CLAUDE.md | Merge PR #589 to respect setting | Eng | Code review |
| Allowed Branches | Add `beta/endless-mode` to allowed list | Eng | 15 min |
### 6.3 Long-Term Actions (Next Release)
| Item | Action | Owner | Effort |
|------|--------|-------|--------|
| Documentation Sync | Implement CI check for doc/code alignment | DevOps | 1 day |
| Beta Badge System | Create Mintlify component for beta feature marking | Docs | 2 hours |
| Feature Flags | Consider feature flag system for documented-but-beta features | Eng | 1 week |
---
## 7. Priority/Severity Assessment
### Severity Matrix
| Issue | Severity | Priority | Rationale |
|-------|----------|----------|-----------|
| Version Channel UI | High | P1 | Backend complete, users actively confused |
| Endless Mode | High | P2 | Documented prominently, users try to configure |
| Troubleshoot Skill | Medium | P1 | Entry point for support, must work |
| Folder CLAUDE.md | Medium | P2 | Settings should work as documented |
| Skills Directory | Medium | P3 | Developer-facing, less user impact |
| Allowed Branches | Low | P3 | Edge case |
| Hook Count | Low | P4 | Cosmetic inconsistency |
| MCP Tool Count | Low | P4 | Minor clarification |
### Recommended Resolution Order
1. **P1 - Immediate**: Fix troubleshoot skill reference (remove or explain)
2. **P1 - Immediate**: Version Channel UI decision (badge or implement)
3. **P2 - This Week**: Endless Mode documentation badges
4. **P2 - This Week**: Folder CLAUDE.md PR #589 merge
5. **P3 - This Sprint**: Architecture documentation update
6. **P4 - Eventually**: Minor inconsistencies
---
## 8. Files Requiring Updates
### Documentation Files
| File | Changes Needed |
|------|---------------|
| `docs/public/troubleshooting.mdx` | Remove troubleshoot skill reference |
| `docs/public/architecture/overview.mdx` | Update to MCP architecture, fix hook count |
| `docs/public/beta-features.mdx` | Add "Beta Only" badges, clarify UI availability |
| `docs/public/endless-mode.mdx` | Add "Beta Only" badge prominently |
| `docs/public/configuration.mdx` | Mark `FOLDER_CLAUDEMD_ENABLED` as coming soon or remove |
| `CLAUDE.md` (root) | Verify hook count |
### Code Files
| File | Changes Needed |
|------|---------------|
| `src/services/worker/http/routes/SettingsRoutes.ts` | Add `beta/endless-mode` to allowed branches |
| `src/services/worker/agents/ResponseProcessor.ts` | Check `FOLDER_CLAUDEMD_ENABLED` setting (via PR #589) |
| `src/shared/SettingsDefaultsManager.ts` | Add `CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED` setting |
---
## 9. Appendix
### Related Issues and PRs
| Reference | Description | Status |
|-----------|-------------|--------|
| #333 | Version Channel UI | Closed |
| #436 | Version Channel UI | Closed |
| #461 | Version Channel UI | Closed |
| #366 | Endless Mode | Closed |
| #403 | Endless Mode | Closed |
| #416 | Endless Mode | Closed |
| #589 | Folder CLAUDE.md setting fix | Open |
| #600 | This documentation audit | Open |
### Verification Commands
```bash
# Check for Version Channel UI
grep -r "Version Channel\|version.*channel" src/ui/
# Check for Endless Mode settings
grep -r "ENDLESS_MODE" src/
# Check skills directory
ls -la plugin/skills/
# Check settings validation
grep -A 50 "settingKeys" src/services/worker/http/routes/SettingsRoutes.ts
```
---
*Report generated from analysis of Issue #600 and codebase inspection on 2026-01-07.*

View File

@@ -0,0 +1,430 @@
# Issue #602: PostToolUse Error - Worker Service Failed to Start (Windows)
**Report Date:** 2026-01-07
**Issue Author:** onurtirpan
**Issue Created:** 2026-01-07
**Labels:** bug
**Severity:** HIGH
**Priority:** P1 - Critical
---
## 1. Executive Summary
A Windows 11 user running Claude Code 0.2.76 with claude-mem v9.0.0 is experiencing complete plugin failure. The worker service cannot start during PostToolUse hook execution, resulting in long delays and multiple cascading errors. This is a systemic Windows platform compatibility issue that prevents the entire memory system from functioning.
### Key Symptoms
- "Plugin hook bun worker-service.cjs start failed to start: The operation was aborted"
- Multiple "Worker failed to start (health check timeout)" errors
- "Failed to start server. Is port 37777 in use?"
- "wmic is not recognized" - Windows command compatibility issue
- Database not initialized errors
### Impact
- **Complete loss of memory functionality** on Windows
- Long delays during Claude Code operations
- User workflow disruption
---
## 2. Problem Analysis
### 2.1 Error Chain Analysis
The reported errors form a cascade failure pattern:
```
1. PostToolUse hook triggered
└── 2. worker-service.cjs start command executed
└── 3. Bun spawns worker process
└── 4. Worker startup timeout (operation aborted)
└── 5. Health check fails repeatedly
└── 6. "Is port 37777 in use?" check fails
└── 7. "wmic is not recognized" - WMIC unavailable
└── 8. Database cannot initialize
└── 9. Plugin hook failure
```
### 2.2 Error Categories
| Error Type | Root Cause | Severity |
|------------|-----------|----------|
| "operation was aborted" | Hook timeout exceeded before worker ready | High |
| "health check timeout" | Worker startup takes too long on Windows | High |
| "Is port 37777 in use?" | Previous zombie process holding port | Medium |
| "wmic is not recognized" | WMIC deprecated/removed in Windows 11 | Critical |
| "Database not initialized" | Worker never reached ready state | Consequential |
---
## 3. Technical Details
### 3.1 Affected Components
| Component | File Path | Role |
|-----------|-----------|------|
| Hook Configuration | `plugin/hooks/hooks.json` | Defines PostToolUse command chain |
| Worker Service | `src/services/worker-service.ts` | Main worker orchestrator |
| Process Manager | `src/services/infrastructure/ProcessManager.ts` | Windows process enumeration via WMIC |
| Health Monitor | `src/services/infrastructure/HealthMonitor.ts` | Port and health check logic |
| Server | `src/services/server/Server.ts` | HTTP server on port 37777 |
### 3.2 Hook Configuration (hooks.json)
```json
{
"PostToolUse": [{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start",
"timeout": 60
},
{
"type": "command",
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/save-hook.js\"",
"timeout": 120
}
]
}]
}
```
The 60-second timeout for worker startup may be insufficient on Windows systems, especially during first-time initialization when database creation, Chroma vector store setup, and MCP server connection all must complete.
### 3.3 Platform Timeouts
Current timeout configuration in `src/shared/hook-constants.ts`:
```typescript
export const HOOK_TIMEOUTS = {
DEFAULT: 300000, // 5 minutes
HEALTH_CHECK: 30000, // 30 seconds
WORKER_STARTUP_WAIT: 1000,
WORKER_STARTUP_RETRIES: 300,
PRE_RESTART_SETTLE_DELAY: 2000,
WINDOWS_MULTIPLIER: 1.5 // Only 1.5x for Windows
} as const;
```
### 3.4 WMIC Dependency
The `ProcessManager.ts` uses WMIC for Windows process enumeration:
```typescript
// Line 91-92: getChildProcesses()
const cmd = `wmic process where "parentprocessid=${parentPid}" get processid /format:list`;
// Line 174: cleanupOrphanedProcesses()
const cmd = `wmic process where "name like '%python%' and commandline like '%chroma-mcp%'" get processid /format:list`;
```
**Critical Issue:** WMIC (Windows Management Instrumentation Command-line) has been deprecated since Windows 10 version 21H1 and is being removed in Windows 11. Users with clean Windows 11 installations may not have WMIC available.
---
## 4. Impact Assessment
### 4.1 User Impact
| Impact Category | Description |
|-----------------|-------------|
| Functionality | Complete loss of memory features on Windows |
| Performance | Long delays during Claude Code operations (60s+ timeouts) |
| User Experience | Error messages displayed, interrupted workflows |
| Data | No observations being saved, no context injection |
### 4.2 Scope
- **Affected Platform:** Windows 11 (Build 26100+)
- **Affected Shell:** PowerShell 7
- **Affected Version:** claude-mem 9.0.0
- **Claude Code Version:** 0.2.76
- **Estimated User Base:** All Windows 11 users with modern builds
### 4.3 Related Issues
| Issue | Title | Status | Relationship |
|-------|-------|--------|--------------|
| #517 | PowerShell `$_` escaping in Git Bash | Fixed (v9.0.0) | Same component (ProcessManager) |
| #555 | Windows hooks IPC issues | Open | Related Windows hook execution |
| #324 | Windows 11 64-bit system issues | Open | Same platform |
---
## 5. Root Cause Analysis
### 5.1 Primary Root Cause: WMIC Deprecation
WMIC is no longer available by default on Windows 11. When `cleanupOrphanedProcesses()` runs during worker initialization, it fails with "wmic is not recognized", causing the error to be swallowed but subsequent operations to fail.
**Evidence from ProcessManager.ts lines 167-218:**
```typescript
export async function cleanupOrphanedProcesses(): Promise<void> {
const isWindows = process.platform === 'win32';
// ...
if (isWindows) {
// Windows: Use WMIC to find chroma-mcp processes
const cmd = `wmic process where "name like '%python%' and commandline like '%chroma-mcp%'" get processid /format:list`;
const { stdout } = await execAsync(cmd, { timeout: 60000 });
// ...
}
}
```
### 5.2 Secondary Root Cause: Insufficient Timeouts
The hooks.json defines a 60-second timeout for worker startup, but on Windows:
1. WMIC command execution adds latency
2. Database initialization is slower on Windows file systems
3. MCP server initialization has a 5-minute timeout but the hook only waits 60 seconds
4. The WINDOWS_MULTIPLIER of 1.5x is applied inconsistently
### 5.3 Tertiary Root Cause: Zombie Port Issue
The "Is port 37777 in use?" error indicates previous worker processes may not have exited cleanly. This is a known issue (documented in `docs/reports/2026-01-06--windows-woes-comprehensive-report.md`) where Bun's socket cleanup bug on Windows leaves zombie ports.
### 5.4 Quaternary Root Cause: Error Cascade
When `cleanupOrphanedProcesses()` fails silently, the worker attempts to start but:
1. Previous zombie processes may still hold port 37777
2. Health checks fail because the new worker cannot bind
3. The "operation was aborted" error triggers when the 60s hook timeout expires
4. Database initialization never completes
---
## 6. Recommended Solutions
### 6.1 Immediate Fix: Replace WMIC with PowerShell CIM Cmdlets (P0)
**Replace WMIC commands with PowerShell Get-CimInstance:**
```typescript
// Before (ProcessManager.ts line 91-92)
const cmd = `wmic process where "parentprocessid=${parentPid}" get processid /format:list`;
// After
const cmd = `powershell -NoProfile -Command "Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq ${parentPid} } | Select-Object -ExpandProperty ProcessId"`;
```
```typescript
// Before (ProcessManager.ts line 174)
const cmd = `wmic process where "name like '%python%' and commandline like '%chroma-mcp%'" get processid /format:list`;
// After
const cmd = `powershell -NoProfile -Command "Get-CimInstance Win32_Process | Where-Object { $_.Name -like '*python*' -and $_.CommandLine -like '*chroma-mcp*' } | Select-Object -ExpandProperty ProcessId"`;
```
**Note:** This reintroduces Issue #517 concerns about `$_` in Git Bash. Use proper escaping or run via Node.js `child_process.spawn` with `shell: false` and explicit `powershell.exe` path.
### 6.2 Alternative Fix: Use tasklist Command (P0)
A WMIC-free alternative using built-in Windows commands:
```typescript
// For process enumeration
const cmd = `tasklist /FI "IMAGENAME eq python*" /FO CSV /NH`;
// Parse CSV output to get PIDs
```
### 6.3 Increase Windows Timeouts (P1)
Update `plugin/hooks/hooks.json` to use longer Windows-appropriate timeouts:
```json
{
"PostToolUse": [{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start",
"timeout": 120
}
]
}]
}
```
Update `src/shared/hook-constants.ts`:
```typescript
export const HOOK_TIMEOUTS = {
// ...
WINDOWS_MULTIPLIER: 2.5 // Increase from 1.5 to 2.5
} as const;
```
### 6.4 Add WMIC Availability Detection (P1)
Add graceful fallback when WMIC is unavailable:
```typescript
async function isWmicAvailable(): Promise<boolean> {
try {
await execAsync('wmic os get caption', { timeout: 5000 });
return true;
} catch {
return false;
}
}
export async function cleanupOrphanedProcesses(): Promise<void> {
if (process.platform !== 'win32') {
// Unix implementation
return;
}
const useWmic = await isWmicAvailable();
const cmd = useWmic
? `wmic process where "name like '%python%' ..." get processid /format:list`
: `powershell -NoProfile -Command "Get-CimInstance Win32_Process | ..."`;
// Continue with appropriate parser
}
```
### 6.5 Improve Port Cleanup on Windows (P2)
Ensure proper cleanup before worker restart:
```typescript
// Add to ProcessManager.ts
export async function forceReleasePort(port: number): Promise<void> {
if (process.platform !== 'win32') return;
try {
// Find process using the port
const { stdout } = await execAsync(
`powershell -NoProfile -Command "(Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue).OwningProcess | Sort-Object -Unique"`
);
const pids = stdout.trim().split('\n').filter(p => p.trim());
for (const pid of pids) {
await forceKillProcess(parseInt(pid, 10));
}
} catch {
// Port not in use or access denied
}
}
```
### 6.6 Improve Error Messaging (P2)
Add user-friendly error messages with actionable guidance:
```typescript
// In HealthMonitor.ts
export async function waitForHealth(port: number, timeoutMs: number): Promise<boolean> {
// ... existing logic ...
if (!ready && process.platform === 'win32') {
logger.warn('SYSTEM', 'Windows worker startup slow. Check:');
logger.warn('SYSTEM', ' 1. Is antivirus scanning the plugin folder?');
logger.warn('SYSTEM', ' 2. Is port 37777 blocked by firewall?');
logger.warn('SYSTEM', ' 3. Try: netstat -ano | findstr 37777');
}
return ready;
}
```
---
## 7. Priority/Severity Assessment
### 7.1 Severity Matrix
| Factor | Assessment | Score |
|--------|-----------|-------|
| User Impact | Complete feature loss | 5/5 |
| Frequency | Every operation on affected systems | 5/5 |
| Workaround Available | None | 5/5 |
| Data Loss Risk | No data saved | 4/5 |
| Affected Users | All Windows 11 users | 4/5 |
**Overall Severity: CRITICAL (23/25)**
### 7.2 Priority Recommendation
| Priority | Action | Timeline |
|----------|--------|----------|
| P0 | Replace WMIC with PowerShell CIM cmdlets | Immediate (v9.0.1) |
| P1 | Increase Windows timeouts | Same release |
| P1 | Add WMIC availability detection | Same release |
| P2 | Improve port cleanup | Next minor release |
| P2 | Better error messaging | Next minor release |
### 7.3 Testing Requirements
1. **Unit Tests:**
- Test `cleanupOrphanedProcesses()` with mock WMIC failure
- Test `getChildProcesses()` with PowerShell fallback
- Test timeout multiplier application
2. **Integration Tests:**
- Windows 11 clean install (no WMIC)
- Windows 10 with WMIC available
- Git Bash environment with PowerShell commands
3. **Manual Verification:**
- Confirm worker starts successfully on Windows 11
- Confirm health checks pass within timeout
- Confirm orphaned process cleanup works
---
## 8. Files to Modify
| File | Change Required |
|------|-----------------|
| `src/services/infrastructure/ProcessManager.ts` | Replace WMIC with PowerShell or tasklist |
| `src/shared/hook-constants.ts` | Increase WINDOWS_MULTIPLIER |
| `plugin/hooks/hooks.json` | Increase worker start timeout |
| `src/services/infrastructure/HealthMonitor.ts` | Add Windows-specific error messages |
| `docs/public/troubleshooting.mdx` | Document Windows 11 requirements |
---
## 9. Appendix
### 9.1 Related Documentation
- `docs/reports/2026-01-06--windows-woes-comprehensive-report.md`
- `docs/reports/2026-01-04--issue-517-windows-powershell-analysis.md`
- `docs/reports/2026-01-05--issue-555-windows-hooks-ipc-false.md`
### 9.2 WMIC Deprecation Timeline
| Windows Version | WMIC Status |
|-----------------|-------------|
| Windows 10 (pre-21H1) | Available by default |
| Windows 10 21H1+ | Deprecated, feature on demand |
| Windows 11 (initial) | Available but deprecated |
| Windows 11 22H2+ | Being removed progressively |
| Windows 11 23H2+ | Not installed by default |
### 9.3 PowerShell Equivalent Commands
| WMIC Command | PowerShell Equivalent |
|--------------|----------------------|
| `wmic process list` | `Get-CimInstance Win32_Process` |
| `wmic process where "name='x'"` | `Get-CimInstance Win32_Process \| Where-Object { $_.Name -eq 'x' }` |
| `wmic process get processid` | `(Get-CimInstance Win32_Process).ProcessId` |
### 9.4 User Workaround (Temporary)
Until a fix is released, users can manually install WMIC:
1. Open Settings > Apps > Optional Features
2. Click "Add a feature"
3. Search for "WMIC (Windows Management Instrumentation Command-line)"
4. Install and restart terminal
**Note:** This is not a recommended long-term solution as WMIC will eventually be fully removed.
---
*Report generated by Claude Opus 4.5 for issue #602*

View File

@@ -0,0 +1,427 @@
# Technical Report: Worker Daemon Child Process Leak
**Issue:** #603 - Bug: worker-service daemon leaks child claude processes
**Author:** raulk
**Created:** 2026-01-07
**Report Version:** 1.0
**Severity:** Critical
**Priority:** P0 - Immediate attention required
---
## 1. Executive Summary
The `worker-service.cjs --daemon` process spawns Claude subagent processes via the Claude Agent SDK that are not being properly terminated when their tasks complete. Over the course of normal usage (6+ hours), this results in the accumulation of orphaned child processes that consume significant system memory.
**Key Findings:**
- 121 orphaned `claude` processes accumulated over ~6 hours
- Total memory consumption: ~44GB RSS
- Average memory per process: ~372MB
- Root cause: Missing child process cleanup after SDK query completion
- The issue affects Linux systems and potentially all platforms
**Recommendation:** Implement explicit child process tracking and cleanup in the SDK agent lifecycle, and add process reaping on generator completion.
---
## 2. Problem Analysis
### 2.1 Observed Behavior
The reporter documented the following scenario:
**Parent daemon process (running 7+ hours):**
```
PID PPID RSS(KB) ELAPSED COMMAND
4118969 1 161656 07:28:16 bun ~/.claude/plugins/cache/thedotmack/claude-mem/9.0.0/scripts/worker-service.cjs --daemon
```
**Sample of leaked children (121 total, all parented to daemon):**
```
PID PPID RSS(KB) ELAPSED COMMAND
1927 4118969 377308 06:21:16 claude --output-format stream-json --verbose --input-format stream-json --model claude-sonnet-4-5 --disallowedTools Bash,Read,Write,Edit,Grep,Glob,WebFetch,WebSearch,Task,NotebookEdit,AskUserQuestion,TodoWrite --setting-sources --permission-mode default
2834 4118969 384716 06:20:44 claude --output-format stream-json [...]
3988 4118969 381844 06:20:15 claude --output-format stream-json --resume <session-id> [...]
5938 4118969 382816 06:19:37 claude --output-format stream-json --resume <session-id> [...]
11503 4118969 381276 06:16:12 claude --output-format stream-json --resume <session-id> [...]
```
### 2.2 Reproduction Steps
1. Use claude-mem normally throughout a work session
2. Run: `ps -o pid,ppid,rss,etime --no-headers | awk '$2 == '$(pgrep -f worker-service.cjs)`
3. Count grows over time without bound
### 2.3 Expected Behavior
Child claude processes should terminate when their task completes, or the daemon should reap them.
---
## 3. Technical Details
### 3.1 Architecture Overview
The claude-mem worker service uses a modular architecture:
```
WorkerService (worker-service.ts)
|
+-- SDKAgent (SDKAgent.ts)
| |
| +-- query() from @anthropic-ai/claude-agent-sdk
| |
| +-- Spawns `claude` CLI subprocess
|
+-- SessionManager (SessionManager.ts)
| |
| +-- Manages active sessions
| +-- Event-driven message queues
|
+-- ProcessManager (ProcessManager.ts)
|
+-- Child process enumeration
+-- Graceful shutdown cleanup
```
### 3.2 SDK Agent Child Process Spawning
The `SDKAgent.startSession()` method invokes the Claude Agent SDK's `query()` function:
```typescript
// src/services/worker/SDKAgent.ts (lines 100-114)
const queryResult = query({
prompt: messageGenerator,
options: {
model: modelId,
...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: session.memorySessionId }),
disallowedTools,
abortController: session.abortController,
pathToClaudeCodeExecutable: claudePath
}
});
```
The `query()` function internally spawns a `claude` CLI subprocess with the parameters visible in the leaked process list:
- `--output-format stream-json`
- `--verbose`
- `--input-format stream-json`
- `--model claude-sonnet-4-5`
- `--disallowedTools ...`
- `--setting-sources`
- `--permission-mode default`
### 3.3 Session Lifecycle
Sessions are managed through the following flow:
1. **Initialization:** `SessionRoutes.handleSessionInit()` creates a session and starts a generator
2. **Processing:** `SDKAgent.startSession()` runs the query loop, processing messages from the queue
3. **Completion:** Generator promise resolves, triggering cleanup in `finally` block
The relevant generator lifecycle code in `SessionRoutes.ts` (lines 137-216):
```typescript
session.generatorPromise = agent.startSession(session, this.workerService)
.catch(error => { /* error handling */ })
.finally(() => {
session.generatorPromise = null;
session.currentProvider = null;
this.workerService.broadcastProcessingStatus();
// Crash recovery logic...
if (!wasAborted) {
// Check for pending work and potentially restart
}
});
```
### 3.4 Graceful Shutdown Implementation
The existing shutdown mechanism in `GracefulShutdown.ts` (lines 49-90) does handle child processes, but **only during daemon shutdown**:
```typescript
export async function performGracefulShutdown(config: GracefulShutdownConfig): Promise<void> {
// STEP 1: Enumerate all child processes BEFORE we start closing things
const childPids = await getChildProcesses(process.pid);
// ... other cleanup steps ...
// STEP 6: Force kill any remaining child processes (Windows zombie port fix)
if (childPids.length > 0) {
for (const pid of childPids) {
await forceKillProcess(pid);
}
await waitForProcessesExit(childPids, 5000);
}
}
```
**Critical Gap:** This cleanup only runs when the daemon itself shuts down, not when individual SDK sessions complete.
---
## 4. Impact Assessment
### 4.1 Resource Consumption
| Metric | Value |
|--------|-------|
| Leaked processes | 121 |
| Total RSS | ~44GB |
| Average per process | ~372MB |
| Accumulation rate | ~20 processes/hour |
| Time to exhaustion (64GB system) | ~3 hours |
### 4.2 System Effects
1. **Memory Exhaustion:** Systems with limited RAM will experience OOM conditions
2. **Performance Degradation:** Swap thrashing as memory fills
3. **Process Table Pollution:** Maximum PID limits may be approached
4. **User Experience:** System becomes unresponsive during extended sessions
### 4.3 Affected Platforms
- **Linux (confirmed):** Ubuntu reported by issue author
- **macOS (likely):** Same process spawning mechanism
- **Windows (potentially different):** Uses different child process tracking
---
## 5. Root Cause Analysis
### 5.1 Primary Root Cause
**The SDK's `query()` function spawns a child `claude` process that is not being explicitly terminated when the async iterator completes.**
The `SDKAgent.startSession()` method:
1. Creates an async generator via `query()`
2. Iterates over messages via `for await (const message of queryResult)`
3. When iteration completes (naturally or via abort), the generator resolves
4. **No explicit cleanup of the underlying child process occurs**
### 5.2 Contributing Factors
1. **No Child Process Tracking:** The codebase does not maintain a registry of spawned child processes during normal operation - only during shutdown enumeration.
2. **AbortController Not Triggering Process Kill:** While sessions have an `abortController`, signaling abort to the SDK iterator does not guarantee the underlying `claude` process terminates.
3. **Generator Finally Block Missing Process Cleanup:** The `finally` block in `SessionRoutes.startGeneratorWithProvider()` handles state cleanup but does not explicitly kill child processes.
4. **SDK Abstraction Hiding Process Details:** The `@anthropic-ai/claude-agent-sdk` abstracts the subprocess management, making it difficult to access and terminate the child process directly.
### 5.3 Code Path Analysis
```
User Session Complete
|
v
SDKAgent.startSession() completes for-await loop
|
v
Generator promise resolves
|
v
SessionRoutes finally block executes
|
+-- session.generatorPromise = null
+-- session.currentProvider = null
+-- broadcastProcessingStatus()
+-- Check pending work
|
v
[MISSING] Child process termination
|
v
Claude subprocess continues running (LEAKED)
```
---
## 6. Recommended Solutions
### 6.1 Solution A: SDK-Level Child Process Tracking (Preferred)
Add explicit child process tracking to the SDKAgent class:
```typescript
// src/services/worker/SDKAgent.ts
export class SDKAgent {
private activeChildProcesses: Map<number, { pid: number, sessionDbId: number }> = new Map();
async startSession(session: ActiveSession, worker?: WorkerRef): Promise<void> {
// Before query(), track that we're about to spawn
const queryResult = query({...});
// After first message, capture the PID if available
// Note: May require SDK modification to expose PID
try {
for await (const message of queryResult) {
// ... existing message handling
}
} finally {
// Cleanup: Kill any child process for this session
this.cleanupSessionProcess(session.sessionDbId);
}
}
private cleanupSessionProcess(sessionDbId: number): void {
// Find and terminate process for this session
// Requires either SDK enhancement or platform-specific process enumeration
}
}
```
**Challenges:** The SDK does not currently expose the child process PID.
### 6.2 Solution B: Session-Level Process Enumeration and Cleanup
Add process cleanup to the session completion flow:
```typescript
// src/services/worker/http/routes/SessionRoutes.ts
private startGeneratorWithProvider(session, provider, source): void {
const parentPid = process.pid;
const preExistingPids = new Set(await getChildProcessesForSession(parentPid, 'claude'));
session.generatorPromise = agent.startSession(session, this.workerService)
.finally(async () => {
// Find new child processes that appeared during this session
const currentPids = await getChildProcessesForSession(parentPid, 'claude');
const newPids = currentPids.filter(pid => !preExistingPids.has(pid));
// Terminate orphaned processes
for (const pid of newPids) {
await forceKillProcess(pid);
}
// ... existing cleanup
});
}
```
### 6.3 Solution C: Periodic Orphan Reaper (Mitigation)
Add a background task that periodically identifies and terminates leaked processes:
```typescript
// src/services/worker/OrphanReaper.ts
export class OrphanReaper {
private interval: NodeJS.Timer | null = null;
start(intervalMs: number = 60000): void {
this.interval = setInterval(async () => {
const orphans = await this.findOrphanedClaudeProcesses();
for (const pid of orphans) {
await forceKillProcess(pid);
}
}, intervalMs);
}
private async findOrphanedClaudeProcesses(): Promise<number[]> {
// Find claude processes parented to the worker daemon
// that have been running longer than expected (e.g., > 30 minutes)
}
}
```
**Pros:** Works without SDK modifications
**Cons:** Reactive rather than proactive; processes leak for up to interval duration
### 6.4 Solution D: Request SDK Enhancement
File an issue with the Claude Agent SDK requesting:
1. Exposure of child process PID in query result
2. Built-in cleanup on iterator completion
3. Explicit `close()` or `terminate()` method
### 6.5 Recommended Implementation Order
1. **Immediate (P0):** Implement Solution C (Orphan Reaper) as a mitigation
2. **Short-term (P1):** Implement Solution B (Session-Level Cleanup)
3. **Medium-term (P2):** Pursue Solution D (SDK Enhancement) with Anthropic
4. **Long-term (P3):** Implement Solution A once SDK provides PID access
---
## 7. Priority/Severity Assessment
### 7.1 Severity: Critical
- **Data Loss:** No
- **System Instability:** Yes - memory exhaustion
- **User Impact:** High - system becomes unusable
- **Scope:** All users with extended sessions
### 7.2 Priority: P0 - Immediate
- **Frequency:** Every session creates leaked processes
- **Accumulation:** Unbounded growth
- **Workaround:** Manual daemon restart (disruptive)
- **Business Impact:** Renders product unusable for long sessions
### 7.3 Effort Estimate
| Solution | Effort | Risk |
|----------|--------|------|
| Orphan Reaper (C) | 2-4 hours | Low |
| Session Cleanup (B) | 4-8 hours | Medium |
| SDK Enhancement (D) | External dependency | - |
| Full Tracking (A) | 8-16 hours | Medium |
---
## 8. References
- **Issue:** https://github.com/thedotmack/claude-mem/issues/603
- **Source Files:**
- `/src/services/worker/SDKAgent.ts` - SDK query invocation
- `/src/services/worker/SessionManager.ts` - Session lifecycle
- `/src/services/worker/http/routes/SessionRoutes.ts` - Generator management
- `/src/services/infrastructure/ProcessManager.ts` - Process utilities
- `/src/services/infrastructure/GracefulShutdown.ts` - Shutdown cleanup
- **Related Code:**
- `@anthropic-ai/claude-agent-sdk` - External SDK spawning processes
---
## 9. Appendix: Process Enumeration Reference
### Current getChildProcesses Implementation
```typescript
// src/services/infrastructure/ProcessManager.ts
export async function getChildProcesses(parentPid: number): Promise<number[]> {
if (process.platform !== 'win32') {
return []; // NOTE: Only implemented for Windows!
}
// Windows implementation using wmic
const cmd = `wmic process where "parentprocessid=${parentPid}" get processid /format:list`;
// ...
}
```
**Critical Finding:** The `getChildProcesses` function is currently **Windows-only** and returns an empty array on Linux/macOS. This means the Linux user reporting the issue has no built-in cleanup mechanism.
### Required Fix for Linux/macOS
```typescript
export async function getChildProcesses(parentPid: number): Promise<number[]> {
if (process.platform === 'win32') {
// Existing Windows implementation
} else {
// Unix implementation
const { stdout } = await execAsync(`pgrep -P ${parentPid}`);
return stdout.trim().split('\n').map(Number).filter(n => !isNaN(n));
}
}
```
---
*Report prepared by Claude Code analysis of codebase and issue #603*

File diff suppressed because it is too large Load Diff

View File

@@ -12,11 +12,6 @@
| #34350 | 11:12 PM | ✅ | Version 8.5.0 Build Completed Successfully | ~425 |
| #34214 | 10:07 PM | 🔵 | Cursor Integration Feature Set Discovered via Memory Search | ~427 |
| #34208 | 10:00 PM | ✅ | claude-mem v8.2.10 built and synced to marketplace | ~416 |
| #34163 | 9:38 PM | ✅ | Project rebuilt with updated interactive setup wizard | ~326 |
| #34092 | 9:02 PM | ✅ | Built claude-mem project with updated interactive setup wizard | ~452 |
| #33997 | 7:10 PM | ✅ | Version Bumped to 8.2.10 | ~179 |
| #33996 | " | 🟣 | Built claude-mem v8.2.10 with all hooks and services | ~387 |
| #33982 | 7:08 PM | ✅ | Staged Version Mismatch Fix Changes | ~333 |
### Dec 30, 2025
@@ -84,4 +79,12 @@
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37545 | 4:47 PM | ✅ | Issue #544 Analysis Report Created for mem-search Skill Messaging Problem | ~480 |
### Jan 7, 2026
**package.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38186 | 7:33 PM | 🟣 | Claude-mem plugin v9.0.0 built and deployed to marketplace | ~327 |
| #38120 | 5:46 PM | 🔴 | Rebuilt all plugin hooks and worker service | ~278 |
</claude-mem-context>

View File

@@ -3,107 +3,29 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 27, 2025
### Oct 25, 2025
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33090 | 7:05 PM | 🔵 | Claude-mem hook configuration reviewed for session disconnect investigation | ~331 |
| #33038 | 5:14 PM | 🔵 | PR 462 Code Review Identifies Critical Endpoint Mismatch and Worker Restart Issues | ~475 |
| #33025 | 5:00 PM | 🟣 | Automated worker restart on plugin updates | ~391 |
| #33017 | 4:57 PM | ✅ | Auto-Restart Feature Deployed to Production Version 8.2.2 | ~367 |
| #33014 | 4:56 PM | 🔄 | SessionStart Hook Reordered for Immediate Worker Restart | ~380 |
| #33012 | " | 🔵 | Plugin Hook Chain Orchestrates Worker Lifecycle | ~412 |
| #33007 | 4:54 PM | 🔵 | Worker Service Lifecycle and Version Mismatch Detection Analysis | ~530 |
| #33006 | 4:47 PM | 🔴 | Changed SessionStart hook from restart to start command | ~311 |
| #33001 | 4:44 PM | ⚖️ | Lockfile-Based Concurrency Control for Windows Multi-Session Fix | ~513 |
| #32996 | 4:42 PM | ⚖️ | Implementation Plan: Atomic Lockfile Strategy for Windows Concurrency Fix | ~639 |
| #32995 | 4:40 PM | 🔵 | Critical Finding: Windows Managed Mode Not Activated in Hooks | ~657 |
| #2518 | 11:47 PM | 🔴 | Removed Invalid 'matcher' Field from SessionStart Hook | ~228 |
| #2517 | " | 🔵 | Project hooks.json Template Also Empty | ~222 |
| #2501 | 11:11 PM | 🔵 | Context Hook Fails Due to Missing @anthropic-ai/sdk Dependency | ~245 |
### Dec 28, 2025
### Oct 27, 2025
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33323 | 3:09 PM | 🔴 | Fixed Windows multi-session worker race condition causing hangs | ~513 |
| #33318 | " | 🔴 | Fixed Worker Auto-Restart Shutdown Endpoint and Port Configuration | ~411 |
| #33284 | 3:07 PM | 🔄 | Consolidated Worker Lifecycle Management (-580 Lines) | ~327 |
| #33271 | 2:59 PM | ⚖️ | Plan Created to Fix Worker Lifecycle in 8 Phases | ~399 |
| #33269 | " | 🔵 | PR #456 Broke Worker Background Execution | ~365 |
| #33266 | 2:58 PM | 🟣 | Test coverage for self-spawn worker pattern | ~391 |
| #33263 | " | 🔴 | Increased timeout limits across system for slow systems compatibility | ~463 |
| #2718 | 12:00 AM | 🔴 | Removed incorrect failOnError configuration from hook | ~165 |
### Dec 29, 2025
### Nov 18, 2025
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33960 | 7:00 PM | 🔵 | Hook Chain Architecture in hooks.json | ~389 |
| #33905 | 5:18 PM | 🟣 | Platform-Native Worker Executable Compilation | ~498 |
| #33895 | 5:13 PM | 🟣 | Implemented install-time worker executable compilation | ~423 |
| #33888 | 5:12 PM | ✅ | Worker Service Command Simplified in Plugin Hooks | ~251 |
| #33869 | 4:47 PM | 🔵 | Claude Code Hook System Integration for Memory Lifecycle Management | ~477 |
| #33868 | " | ⚖️ | Windows standalone executable implementation plan designed | ~590 |
| #33858 | 4:34 PM | 🔵 | Hook execution configuration uses mixed node and bun commands | ~402 |
| #33854 | 4:33 PM | 🔵 | Worker service build and execution architecture mapped | ~509 |
| #11518 | 8:22 PM | 🔵 | Smart Contextualization Switched from Skill to HTTP API | ~498 |
### Dec 30, 2025
### Dec 24, 2025
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34392 | 1:41 PM | 🔵 | Plugin Hooks Architecture Shows No Cleanup Hook for Session Termination | ~396 |
### Dec 31, 2025
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34687 | 3:39 PM | 🔵 | Hook Configuration Uses CLAUDE_PLUGIN_ROOT Environment Variable | ~387 |
### Jan 2, 2026
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35911 | 2:51 PM | 🔵 | Hooks.json Defines Timeout Values For Hook Execution | ~361 |
### Jan 4, 2026
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36937 | 2:36 AM | 🔵 | Matcher Line History - Added November 2025 | ~203 |
| #36936 | 2:34 AM | 🔵 | Current SessionStart Hook Configuration Analysis | ~338 |
| #36935 | " | 🔵 | PR #541 Changes - Matcher Removal in SessionStart Hook | ~263 |
### Jan 5, 2026
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38100 | 10:46 PM | 🔵 | Legacy hooks.json still references Bun runtime | ~393 |
| #38057 | 9:48 PM | ✅ | Live Context Branch Changes Hook Runtime from Bun Back to Node | ~449 |
| #38048 | 9:45 PM | 🔴 | PR #558 - Comprehensive Bug Fix and Test Quality Improvement | ~585 |
| #37617 | 5:32 PM | ⚖️ | PR #558 Review Requirements Categorized by Priority | ~637 |
| #37613 | 5:31 PM | 🔵 | PR #558 Review Feedback Analysis | ~544 |
| #37604 | 4:59 PM | 🔴 | Phase 4 Committed - Hook Runtime Mismatch Fixed | ~377 |
| #37603 | " | ✅ | Phase 4 Corrected - smart-install.js Restored to node Runtime | ~385 |
| #37602 | 4:58 PM | ✅ | Reverted smart-install.js to node Runtime | ~301 |
| #37597 | 4:57 PM | 🔴 | Phase 4 Complete - All Hooks Now Use bun Runtime | ~386 |
| #37596 | " | ✅ | Phase 4 Verification - All Commands Now Use bun Runtime | ~325 |
| #37595 | 4:56 PM | 🔴 | Fixed All Hook Commands to Use bun Runtime | ~364 |
| #37594 | " | 🔵 | hooks.json Contains Mixed node and bun Runtime Commands | ~377 |
| #37558 | 4:49 PM | 🔵 | Issue #555 Windows Hook Execution Patterns and Fix Strategy Documented | ~510 |
| #37548 | 4:48 PM | ✅ | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
| #37547 | 4:47 PM | ✅ | Issue #557 Analysis Report Created for Plugin Startup Failure | ~491 |
| #37531 | 4:43 PM | 🔵 | Plugin Hook Configuration and Lifecycle Definition | ~424 |
### Jan 6, 2026
**hooks.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
| #32309 | 3:09 PM | 🔵 | Claude-mem hooks system configuration structure | ~435 |
</claude-mem-context>

View File

@@ -19,11 +19,6 @@
"type": "command",
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\"",
"timeout": 60
},
{
"type": "command",
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js\"",
"timeout": 60
}
]
}

View File

@@ -3,181 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 22, 2025
**code--fr.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31959 | 8:41 PM | 🔵 | French Language Remix Implementation Pattern | ~336 |
| #31883 | 7:12 PM | ✅ | Externalisation des prompts de résumé dans le fichier de configuration JSON français | ~345 |
| #31840 | 6:47 PM | 🔄 | Removed unused header configuration strings from French mode | ~228 |
**code.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31958 | 8:40 PM | 🔵 | Mode System Structure in Claude-Mem | ~304 |
| #31891 | 7:17 PM | 🔴 | Migration des prompts de résumé vers les fichiers de modes pour le support multilingue | ~474 |
| #31869 | 7:03 PM | 🔵 | コードモードJSONファイルのプロンプト構造の確認 | ~196 |
**code--hu.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31941 | 7:57 PM | 🟣 | Hungarian language mode configuration created | ~336 |
**code--es.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31940 | 7:56 PM | 🔵 | Claude-mem supports 28 language localizations for code mode | ~365 |
| #31922 | 7:50 PM | 🔵 | Spanish Language Mode Remix File Structure | ~323 |
| #31875 | 7:07 PM | ✅ | Standardisation du pied de page de résumé en anglais avec exigence linguistique | ~301 |
| #31874 | " | ✅ | Ajout des instructions de résumé au fichier de mode espagnol | ~308 |
| #31871 | 7:04 PM | 🔵 | Examen de la structure des fichiers de modes multilingues | ~354 |
| #31838 | 6:46 PM | 🔄 | Removed unused header configuration strings from Spanish mode | ~240 |
**code--el.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31939 | 7:56 PM | 🟣 | Greek language mode configuration created | ~330 |
**code--it.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31938 | 7:56 PM | 🟣 | Italian language mode configuration created | ~333 |
**code--sv.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31937 | 7:56 PM | 🟣 | Swedish language mode configuration created | ~330 |
**code--ro.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31936 | 7:56 PM | 🟣 | Romanian language mode configuration created | ~328 |
**code--bn.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31935 | 7:56 PM | 🟣 | Bengali language mode configuration created | ~329 |
**code--hi.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31934 | 7:55 PM | 🟣 | Hindi language mode configuration created | ~318 |
**code--id.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31933 | 7:55 PM | 🟣 | Indonesian language mode configuration created | ~307 |
**code--uk.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31932 | 7:54 PM | 🟣 | Ukrainian Language Mode File Created for Code Development Observer | ~330 |
**code--tr.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31931 | 7:53 PM | 🟣 | Turkish Language Mode File Created for Code Development Observer | ~323 |
**code--nl.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31930 | 7:53 PM | 🟣 | Dutch Language Mode File Created for Code Development Observer | ~317 |
**code--cs.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31929 | 7:53 PM | 🟣 | Czech Language Mode File Created for Code Development Observer | ~316 |
**code--pl.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31928 | 7:53 PM | 🟣 | Polish Language Mode File Created for Code Development Observer | ~319 |
**code--ar.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31927 | 7:53 PM | 🟣 | Arabic Language Mode File Created for Code Development Observer | ~320 |
**code--he.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31926 | 7:53 PM | 🟣 | Hebrew Language Mode File Created for Code Development Observer | ~319 |
**code--ja.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31925 | 7:52 PM | 🟣 | Japanese Language Mode File Created for Code Development Observer | ~324 |
| #31881 | 7:10 PM | ✅ | Ajout des prompts de summary au fichier mode japonais | ~269 |
**code--ko.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31924 | 7:52 PM | 🟣 | Korean Language Mode File Created for Code Development Observer | ~318 |
| #31877 | 7:09 PM | 🔵 | Examen du fichier de mode coréen révélant une structure de prompts externalisés | ~372 |
| #31837 | 6:46 PM | 🔄 | Removed unused header configuration strings from Korean mode | ~255 |
**code--de.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31890 | 7:17 PM | 🔵 | Modifications en cours sur les fichiers de modes multilingues et le système de prompts | ~325 |
| #31886 | 7:14 PM | 🔄 | Externalisation du footer de résumé dans la configuration des prompts | ~318 |
| #31841 | 6:47 PM | 🔄 | Removed unused header configuration strings from German mode | ~231 |
**code--pt.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31888 | 7:16 PM | ✅ | Ajout du champ summary_footer aux prompts du mode portugais | ~301 |
| #31842 | 6:47 PM | 🔄 | Removed unused header configuration strings from Portuguese mode | ~225 |
**code--zh.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31884 | 7:13 PM | ✅ | Externalisation des prompts de résumé dans le fichier de configuration JSON chinois | ~290 |
| #31839 | 6:46 PM | 🔄 | Removed unused header configuration strings from Chinese mode | ~260 |
**code--th.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31845 | 6:48 PM | 🔄 | Removed unused header configuration strings from Thai mode | ~215 |
**code--vi.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31844 | 6:47 PM | 🔄 | Removed unused header configuration strings from Vietnamese mode | ~215 |
**code--ru.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31843 | 6:47 PM | 🔄 | Removed unused header configuration strings from Russian mode | ~225 |
### Dec 23, 2025
**email-investigation.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32026 | 7:39 PM | 🔵 | Email Investigation Mode Configuration Located | ~300 |
**code--pt-br.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32297 | 7:50 PM | ✅ | Renamed Portuguese mode file to Brazilian Portuguese | ~191 |
| #32322 | " | ✅ | Updated pt-br mode display name to Brazilian Portuguese | ~221 |
### Dec 24, 2025
**email-investigation.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32384 | 9:18 PM | ✅ | Email investigation mode enhanced with observation granularity guidance | ~340 |
| #32227 | 8:21 PM | 🔴 | Added missing summary prompts to email-investigation mode | ~308 |
| #32209 | 8:16 PM | 🟣 | Email Investigation mode configured for fraud analysis | ~348 |
| #32205 | 7:55 PM | ✅ | Email Investigation Observation Granularity Guidance | ~256 |
### Dec 25, 2025
**email-investigation.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32456 | 5:41 PM | ✅ | Completed merge of main branch into feature/titans-phase1-3 | ~354 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,139 +3,123 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
### Dec 4, 2025
**context-generator.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35982 | 5:09 PM | ✅ | Built and deployed claude-mem version 8.5.4 with LogsModal UI component | ~295 |
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #20052 | 3:23 PM | ✅ | Built and deployed version 6.5.2 to marketplace | ~321 |
### Dec 7, 2025
**worker-service.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35976 | 4:48 PM | | Claude-mem build and marketplace sync completed | ~335 |
| #35925 | 2:53 PM | ✅ | Built Project for Version 8.5.4 Release | ~294 |
| #35815 | 2:26 PM | ✅ | Claude-mem plugin built and deployed to marketplace | ~381 |
| #21251 | 6:06 PM | 🔵 | Context Hook Plugin Architecture and Worker Communication | ~405 |
### Dec 8, 2025
**new-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35952 | 4:42 PM | 🔵 | Hook and Session Test Coverage Discovery | ~323 |
| #22092 | 6:40 PM | 🔵 | Queue Depth Check Not Found in Minified Code | ~217 |
| #22091 | " | 🔵 | Save Hook Script Structure Revealed | ~472 |
| #22085 | 6:34 PM | 🔵 | Examined pre-tool-use-hook.js implementation showing timing-only logic | ~330 |
### Dec 9, 2025
**context-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35873 | 2:39 PM | ✅ | Claude-mem plugin synced to marketplace version 8.5.3 | ~261 |
| #22557 | 1:08 AM | ✅ | Build completed for version 7.0.3 | ~342 |
### Jan 3, 2026
### Dec 10, 2025
**context-generator.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36687 | 11:53 PM | | MCP SDK and esbuild Dependencies Updated | ~332 |
| #36353 | 8:42 PM | 🔵 | Multiple observation table definitions found across codebase | ~280 |
| #36304 | 8:06 PM | 🔄 | Git Status: Phase 4 Changes Ready for Commit | ~570 |
| #23444 | 2:25 PM | 🟣 | Build Pipeline Execution Successful | ~293 |
### Dec 11, 2025
**new-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36682 | 11:45 PM | 🔵 | Build System Successfully Compiles All Hooks and Services | ~290 |
| #24057 | 2:56 PM | | Hook Scripts Shebang Verification | ~294 |
| #24056 | 2:55 PM | ✅ | Worker CLI Shebang Verification | ~258 |
| #24055 | " | ✅ | Build Successful with Bun Runtime Shebangs | ~355 |
### Dec 12, 2025
**worker-service.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
| #36291 | 8:03 PM | 🔄 | Build Verification: Phase 3 & 4 Refactoring Compiles Successfully | ~545 |
| #24636 | 10:46 PM | 🔵 | Duplicate Smart Install Scripts in Project Structure | ~288 |
| #24635 | " | 🔵 | Claude-Mem Smart Install Script Architecture | ~371 |
| #24359 | 7:00 PM | 🟣 | Phase 1 Critical Code Fixes Completed via Agent Task | ~441 |
| #24358 | 6:59 PM | ✅ | Completed Phase 1 Code Fixes for better-sqlite3 Migration | ~385 |
| #24357 | " | ✅ | Removed createRequire Import from smart-install.js | ~284 |
| #24356 | " | ✅ | Removed Native Module Verification from main() Function | ~384 |
| #24355 | " | ✅ | Removed better-sqlite3 Error Detection from runNpmInstall() | ~324 |
| #24354 | 6:58 PM | ✅ | Removed getWindowsErrorHelp() Function from smart-install.js | ~356 |
| #24353 | " | ✅ | Removed verifyNativeModules() Function from smart-install.js | ~340 |
| #24352 | " | ✅ | Removed better-sqlite3 Existence Check from needsInstall() | ~266 |
| #24351 | " | ✅ | Removed BETTER_SQLITE3_PATH Constant from smart-install.js | ~226 |
| #24344 | 6:56 PM | 🔵 | smart-install.js Contains Obsolete better-sqlite3 Dependencies | ~380 |
### Dec 13, 2025
**context-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36111 | 3:43 PM | 🔵 | Plugin Hook System Architecture | ~243 |
| #25286 | 8:41 PM | 🔵 | New Hook Fails with Node.js Path Error | ~298 |
| #25285 | " | 🔵 | Context Hook Runs Successfully with Node.js | ~306 |
| #25283 | " | 🔵 | Bun Wrapper Analysis: Fallback Detection System | ~416 |
### Dec 14, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #26800 | 11:39 PM | ✅ | Version 7.2.3 Build Complete With Worker Restart Fix | ~394 |
| #26791 | 11:38 PM | ✅ | Phase 3 Complete: Project Built Successfully With Worker Restart Fix | ~446 |
| #26720 | 11:23 PM | 🔵 | Smart Install Handles Dependencies But No Worker Coordination | ~468 |
| #26719 | " | 🔵 | Worker CLI Provides Start/Stop/Restart Commands With Health Check Validation | ~490 |
| #26718 | " | 🔵 | Worker CLI Restart Implementation Details | ~452 |
| #26717 | 11:22 PM | 🔵 | Context Hook Worker Startup Logic Handles Initial Start But Not Post-Update Restart | ~485 |
| #26716 | " | 🔵 | Context Hook Worker Startup Logic Revealed | ~538 |
| #26715 | " | 🔵 | Smart Install Script Handles Dependency Installation Without Worker Restart | ~430 |
| #26052 | 7:13 PM | 🔵 | Examined Minified Context Hook Source Code | ~285 |
| #25686 | 4:22 PM | 🔵 | SessionRoutes tracks missing last_user_message errors at two different locations | ~456 |
| #25685 | " | 🔵 | Progress summary generation system uses Claude to create XML-formatted session checkpoints | ~461 |
### Dec 16, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27554 | 4:48 PM | ✅ | Project built successfully with version 7.3.1 | ~306 |
### Dec 17, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28924 | 7:29 PM | 🔵 | Plugin MCP Server Uses Bun Runtime | ~283 |
### Dec 26, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32983 | 11:04 PM | 🟣 | Complete build and deployment pipeline executed | ~260 |
### Jan 4, 2026
**worker-service.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36926 | 2:26 AM | | Git rebase aborted and working directory restored | ~242 |
| #36701 | 12:01 AM | ✅ | Built Version 8.5.7 Plugin Artifacts | ~406 |
| #36873 | 1:55 AM | 🔵 | Smart-Install Script Analyzed for Homebrew Path Implementation | ~466 |
### Jan 7, 2026
**smart-install.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36914 | 2:24 AM | 🔵 | Recent commit 4d0a10c fixed multiple GitHub issues | ~365 |
| #36829 | 1:40 AM | 🔵 | PR #542 Review Analysis - Multi-Issue Fix Validation | ~562 |
| #36827 | 1:03 AM | | Branch diff shows 1,293 insertions and 98 deletions across 15 files | ~464 |
| #36809 | 12:56 AM | 🟣 | GitHub Issue #527 Anti-Pattern Verification Complete - All Checks Passed | ~495 |
| #36807 | " | 🟣 | Final Verification Confirms Complete Apple Silicon Homebrew Implementation | ~430 |
| #36804 | 12:55 AM | 🟣 | Built File Syntax Validation Passed - Issue #527 Complete | ~378 |
| #36802 | " | 🟣 | Verified Built File Homebrew Path Count | ~398 |
| #36800 | 12:54 AM | 🟣 | Completed All Five Apple Silicon Homebrew Path Updates for GitHub Issue #527 | ~563 |
| #36799 | " | 🟣 | Added Apple Silicon Homebrew Path to plugin installBun Post-Installation Verification | ~456 |
| #36798 | " | 🟣 | Added Apple Silicon Homebrew Path to plugin isUvInstalled Function | ~436 |
| #36797 | 12:53 AM | 🟣 | Added Apple Silicon Homebrew Path to plugin getBunPath Function | ~443 |
| #36796 | " | 🟣 | Added Apple Silicon Homebrew Path to plugin isBunInstalled Function | ~427 |
| #36795 | 12:52 AM | 🟣 | GitHub Issue #527 Completed - Apple Silicon Homebrew Path Support | ~550 |
| #36794 | 12:51 AM | 🔵 | Built File Plugin smart-install.js Requires Apple Silicon Path Updates | ~442 |
| #36772 | 12:42 AM | 🔵 | Smart Install Script Path Arrays Analysis Complete | ~448 |
| #36761 | 12:36 AM | ✅ | Created Implementation Plans for Four GitHub Issues | ~507 |
| #36721 | 12:15 AM | 🔵 | Issue #527 UV Homebrew Path Missing on Apple Silicon | ~492 |
| #36719 | " | 🔵 | Issue #527 uv Homebrew Detection Missing on Apple Silicon Macs | ~526 |
**new-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36921 | 2:25 AM | ✅ | Project built successfully with all hooks and services | ~240 |
### Jan 5, 2026
**worker-service.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38092 | 10:44 PM | ✅ | Built version 9.0.0 with complete plugin bundle | ~329 |
| #38036 | 9:43 PM | 🟣 | Configurable Observation Limits and Enhanced Folder Search | ~418 |
| #37981 | 8:34 PM | 🔴 | Fixed date parsing bug in worker assets | ~268 |
| #37610 | 5:04 PM | ✅ | Committed Rebuilt Plugin Scripts After Source Changes | ~432 |
**context-generator.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38082 | 10:13 PM | ✅ | Merge Conflict Resolution - Kept Feature Branch Versions | ~431 |
| #38076 | 9:53 PM | 🟣 | Worktree-Aware Project Filtering for Unified Timeline Context | ~578 |
| #37574 | 4:52 PM | ✅ | Phase 1 Changes Ready for Commit | ~351 |
**context-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38048 | 9:45 PM | 🔴 | PR #558 - Comprehensive Bug Fix and Test Quality Improvement | ~585 |
**user-message-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37990 | 9:00 PM | 🔵 | CLAUDE_MEM_WORKER_HOST setting used across 19 files | ~289 |
**smart-install.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37558 | 4:49 PM | 🔵 | Issue #555 Windows Hook Execution Patterns and Fix Strategy Documented | ~510 |
| #37548 | 4:48 PM | ✅ | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
**worker-wrapper.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37553 | 4:48 PM | 🔵 | Windows Worker Wrapper Process Management Implementation | ~456 |
### Jan 6, 2026
**cleanup-hook.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
**bun-wrapper.cjs**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
| #38169 | 7:21 PM | 🔵 | SessionStart Hook Output Pattern Investigation Complete | ~464 |
| #38168 | " | 🔵 | Smart-Install Script Outputs All Status Messages to stderr via console.error | ~438 |
| #38167 | 7:20 PM | 🔵 | Context-Hook Uses stdin Event Handlers for Non-TTY JSON Output Mode | ~396 |
| #38166 | " | 🔵 | User-Message-Hook Executes at Top Level with Await and Exit Code 1 | ~423 |
| #38165 | " | 🔵 | Context-Hook Has Minimal Console Output in Compiled Code | ~333 |
| #38164 | " | 🔵 | Worker-Service Script is Large 1575-Line Multi-Purpose Service Manager | ~352 |
| #38163 | 7:19 PM | 🔵 | Worker-Service Script Uses console.log and console.error for Output | ~385 |
| #38162 | " | 🔵 | Smart-Install Script Auto-Installs Bun and UV Dependencies | ~495 |
| #38161 | " | 🔵 | User-Message-Hook Outputs to stderr and Exits with Code 1 | ~211 |
| #38160 | 7:18 PM | 🔵 | Context-Hook Returns JSON with hookSpecificOutput Structure | ~470 |
</claude-mem-context>

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bun
import{stdin as A}from"process";import C from"path";import{homedir as z}from"os";import{readFileSync as q}from"fs";import{appendFileSync as j,existsSync as h,mkdirSync as H,readFileSync as G}from"fs";import{join as T}from"path";import{homedir as K}from"os";var O=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(O||{}),U=T(K(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(U,"logs");h(t)||H(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(U,"settings.json");if(h(t)){let r=G(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=O[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),s=String(t.getMinutes()).padStart(2,"0"),E=String(t.getSeconds()).padStart(2,"0"),c=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${i}:${s}:${E}.${c}`}log(t,r,e,n,i){if(t<this.getLevel())return;this.ensureLogFileInitialized();let s=this.formatTimestamp(new Date),E=O[t].padEnd(5),c=r.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let _="";i!=null&&(i instanceof Error?_=this.getLevel()===0?`
import{stdin as A}from"process";import C from"path";import{homedir as z}from"os";import{readFileSync as q}from"fs";import{appendFileSync as j,existsSync as h,mkdirSync as H,readFileSync as G}from"fs";import{join as T}from"path";import{homedir as K}from"os";var S=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(S||{}),U=T(K(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(U,"logs");h(t)||H(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(U,"settings.json");if(h(t)){let r=G(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=S[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),s=String(t.getMinutes()).padStart(2,"0"),E=String(t.getSeconds()).padStart(2,"0"),c=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${i}:${s}:${E}.${c}`}log(t,r,e,n,i){if(t<this.getLevel())return;this.ensureLogFileInitialized();let s=this.formatTimestamp(new Date),E=S[t].padEnd(5),c=r.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let _="";i!=null&&(i instanceof Error?_=this.getLevel()===0?`
${i.message}
${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?_=`
`+JSON.stringify(i,null,2):_=" "+this.formatData(i));let p="";if(n){let{sessionId:d,memorySessionId:at,correlationId:lt,...R}=n;Object.keys(R).length>0&&(p=` {${Object.entries(R).map(([x,b])=>`${x}=${b}`).join(", ")}}`)}let D=`[${s}] [${E}] [${c}] ${a}${e}${p}${_}`;if(this.logFilePath)try{j(this.logFilePath,D+`
`,"utf8")}catch(d){process.stderr.write(`[LOGGER] Failed to write to log file: ${d}
`)}else process.stderr.write(D+`
`)}debug(t,r,e,n){this.log(0,t,r,e,n)}info(t,r,e,n){this.log(1,t,r,e,n)}warn(t,r,e,n){this.log(2,t,r,e,n)}error(t,r,e,n){this.log(3,t,r,e,n)}dataIn(t,r,e,n){this.info(t,`\u2192 ${r}`,e,n)}dataOut(t,r,e,n){this.info(t,`\u2190 ${r}`,e,n)}success(t,r,e,n){this.info(t,`\u2713 ${r}`,e,n)}failure(t,r,e,n){this.error(t,`\u2717 ${r}`,e,n)}timing(t,r,e,n){this.info(t,`\u23F1 ${r}`,n,{duration:`${e}ms`})}happyPathError(t,r,e,n,i=""){let a=((new Error().stack||"").split(`
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=a?`${a[1].split("/").pop()}:${a[2]}`:"unknown",p={...e,location:_};return this.warn(t,`[HAPPY-PATH] ${r}`,p,n),i}},l=new M;var m={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*m.WINDOWS_MULTIPLIER):o}import{readFileSync as X,writeFileSync as P,existsSync as y,mkdirSync as V}from"fs";import{join as Y,dirname as B}from"path";import{homedir as J}from"os";var I="bugfix,feature,refactor,discovery,decision,change",k="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:Y(J(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:k,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!y(t)){let s=this.getAllDefaults();try{let E=B(t);y(E)||V(E,{recursive:!0}),P(t,JSON.stringify(s,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(E){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,E)}return s}let r=X(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{P(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(s){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,s)}}let i={...this.DEFAULTS};for(let s of Object.keys(this.DEFAULTS))n[s]!==void 0&&(i[s]=n[s]);return i}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function $(o={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=o,i=e||"Worker service connection failed.",s=t?` (port ${t})`:"",E=`${i}${s}
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=a?`${a[1].split("/").pop()}:${a[2]}`:"unknown",p={...e,location:_};return this.warn(t,`[HAPPY-PATH] ${r}`,p,n),i}},l=new M;var m={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*m.WINDOWS_MULTIPLIER):o}import{readFileSync as X,writeFileSync as P,existsSync as y,mkdirSync as V}from"fs";import{join as B,dirname as Y}from"path";import{homedir as J}from"os";var I="bugfix,feature,refactor,discovery,decision,change",k="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:B(J(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:k,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!y(t)){let s=this.getAllDefaults();try{let E=Y(t);y(E)||V(E,{recursive:!0}),P(t,JSON.stringify(s,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(E){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,E)}return s}let r=X(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{P(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(s){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,s)}}let i={...this.DEFAULTS};for(let s of Object.keys(this.DEFAULTS))n[s]!==void 0&&(i[s]=n[s]);return i}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function $(o={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=o,i=e||"Worker service connection failed.",s=t?` (port ${t})`:"",E=`${i}${s}
`;return E+=`To restart the worker:
`,E+=`1. Exit Claude Code completely
@@ -16,4 +16,4 @@ ${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?_=`
If that doesn't work, try: /troubleshoot`),n&&(E=`Worker Error: ${n}
${E}`),E}var Q=C.join(z(),".claude","plugins","marketplaces","thedotmack"),It=N(m.HEALTH_CHECK),S=null;function u(){if(S!==null)return S;let o=C.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(o);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}async function Z(){let o=u();return(await fetch(`http://127.0.0.1:${o}/api/readiness`)).ok}function tt(){let o=C.join(Q,"package.json");return JSON.parse(q(o,"utf-8")).version}async function et(){let o=u(),t=await fetch(`http://127.0.0.1:${o}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function rt(){let o=tt(),t=await et();o!==t&&l.debug("SYSTEM","Version check",{pluginVersion:o,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function v(){for(let r=0;r<75;r++){try{if(await Z()){await rt();return}}catch(e){l.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error($({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}import it from"path";import{statSync as nt,readFileSync as ot}from"fs";import L from"path";var f={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function W(o){let t=L.join(o,".git"),r;try{r=nt(t)}catch{return f}if(!r.isFile())return f;let e;try{e=ot(t,"utf-8").trim()}catch{return f}let n=e.match(/^gitdir:\s*(.+)$/);if(!n)return f;let s=n[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!s)return f;let E=s[1],c=L.basename(o),a=L.basename(E);return{isWorktree:!0,worktreeName:c,parentRepoPath:E,parentProjectName:a}}function st(o){if(!o||o.trim()==="")return l.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:o}),"unknown-project";let t=it.basename(o);if(t===""){if(process.platform==="win32"){let e=o.match(/^([A-Z]):\\/i);if(e){let i=`drive-${e[1].toUpperCase()}`;return l.info("PROJECT_NAME","Drive root detected",{cwd:o,projectName:i}),i}}return l.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:o}),"unknown-project"}return t}function F(o){let t=st(o);if(!o)return{primary:t,parent:null,isWorktree:!1,allProjects:[t]};let r=W(o);return r.isWorktree&&r.parentProjectName?{primary:t,parent:r.parentProjectName,isWorktree:!0,allProjects:[r.parentProjectName,t]}:{primary:t,parent:null,isWorktree:!1,allProjects:[t]}}async function w(o){await v();let t=o?.cwd??process.cwd(),r=F(t),e=u(),n=r.allProjects.join(","),i=`http://127.0.0.1:${e}/api/context/inject?projects=${encodeURIComponent(n)}`,s=await fetch(i);if(!s.ok)throw new Error(`Context generation failed: ${s.status}`);return(await s.text()).trim()}var Et=process.argv.includes("--colors");if(A.isTTY||Et)w(void 0).then(o=>{console.log(o),process.exit(0)});else{let o="";A.on("data",t=>o+=t),A.on("end",async()=>{let t;try{t=o.trim()?JSON.parse(o):void 0}catch(e){throw new Error(`Failed to parse hook input: ${e instanceof Error?e.message:String(e)}`)}let r=await w(t);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:r}})),process.exit(0)})}
${E}`),E}var Q=C.join(z(),".claude","plugins","marketplaces","thedotmack"),It=N(m.HEALTH_CHECK),O=null;function u(){if(O!==null)return O;let o=C.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(o);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function Z(){let o=u();return(await fetch(`http://127.0.0.1:${o}/api/readiness`)).ok}function tt(){let o=C.join(Q,"package.json");return JSON.parse(q(o,"utf-8")).version}async function et(){let o=u(),t=await fetch(`http://127.0.0.1:${o}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function rt(){let o=tt(),t=await et();o!==t&&l.debug("SYSTEM","Version check",{pluginVersion:o,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function v(){for(let r=0;r<75;r++){try{if(await Z()){await rt();return}}catch(e){l.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error($({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}import it from"path";import{statSync as nt,readFileSync as ot}from"fs";import L from"path";var f={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function W(o){let t=L.join(o,".git"),r;try{r=nt(t)}catch{return f}if(!r.isFile())return f;let e;try{e=ot(t,"utf-8").trim()}catch{return f}let n=e.match(/^gitdir:\s*(.+)$/);if(!n)return f;let s=n[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!s)return f;let E=s[1],c=L.basename(o),a=L.basename(E);return{isWorktree:!0,worktreeName:c,parentRepoPath:E,parentProjectName:a}}function st(o){if(!o||o.trim()==="")return l.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:o}),"unknown-project";let t=it.basename(o);if(t===""){if(process.platform==="win32"){let e=o.match(/^([A-Z]):\\/i);if(e){let i=`drive-${e[1].toUpperCase()}`;return l.info("PROJECT_NAME","Drive root detected",{cwd:o,projectName:i}),i}}return l.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:o}),"unknown-project"}return t}function F(o){let t=st(o);if(!o)return{primary:t,parent:null,isWorktree:!1,allProjects:[t]};let r=W(o);return r.isWorktree&&r.parentProjectName?{primary:t,parent:r.parentProjectName,isWorktree:!0,allProjects:[r.parentProjectName,t]}:{primary:t,parent:null,isWorktree:!1,allProjects:[t]}}async function w(o){await v();let t=o?.cwd??process.cwd(),r=F(t),e=u(),n=r.allProjects.join(","),i=`http://127.0.0.1:${e}/api/context/inject?projects=${encodeURIComponent(n)}`,s=await fetch(i);if(!s.ok)throw new Error(`Context generation failed: ${s.status}`);return(await s.text()).trim()}var Et=process.argv.includes("--colors");if(A.isTTY||Et)w(void 0).then(o=>{console.log(o),process.exit(0)});else{let o="";A.on("data",t=>o+=t),A.on("end",async()=>{let t;try{t=o.trim()?JSON.parse(o):void 0}catch(e){throw new Error(`Failed to parse hook input: ${e instanceof Error?e.message:String(e)}`)}let r=await w(t);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:r}})),process.exit(0)})}

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bun
import{stdin as b}from"process";var T=JSON.stringify({continue:!0,suppressOutput:!0});import L from"path";import{homedir as Y}from"os";import{readFileSync as J}from"fs";import{appendFileSync as F,existsSync as h,mkdirSync as H,readFileSync as x}from"fs";import{join as f}from"path";import{homedir as j}from"os";var S=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(S||{}),R=f(j(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=f(R,"logs");h(t)||H(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=f(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=f(R,"settings.json");if(h(t)){let r=x(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=S[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
import{stdin as b}from"process";var T=JSON.stringify({continue:!0,suppressOutput:!0});import L from"path";import{homedir as Y}from"os";import{readFileSync as J}from"fs";import{appendFileSync as F,existsSync as R,mkdirSync as H,readFileSync as x}from"fs";import{join as f}from"path";import{homedir as j}from"os";var S=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(S||{}),h=f(j(),".claude-mem"),m=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=f(h,"logs");R(t)||H(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=f(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=f(h,"settings.json");if(R(t)){let r=x(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=S[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),E=String(t.getMinutes()).padStart(2,"0"),s=String(t.getSeconds()).padStart(2,"0"),c=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${i}:${E}:${s}.${c}`}log(t,r,e,n,i){if(t<this.getLevel())return;this.ensureLogFileInitialized();let E=this.formatTimestamp(new Date),s=S[t].padEnd(5),c=r.padEnd(6),l="";n?.correlationId?l=`[${n.correlationId}] `:n?.sessionId&&(l=`[session-${n.sessionId}] `);let _="";i!=null&&(i instanceof Error?_=this.getLevel()===0?`
${i.message}
${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?_=`
`+JSON.stringify(i,null,2):_=" "+this.formatData(i));let u="";if(n){let{sessionId:d,memorySessionId:nt,correlationId:ot,...D}=n;Object.keys(D).length>0&&(u=` {${Object.entries(D).map(([w,W])=>`${w}=${W}`).join(", ")}}`)}let C=`[${E}] [${s}] [${c}] ${l}${e}${u}${_}`;if(this.logFilePath)try{F(this.logFilePath,C+`
`+JSON.stringify(i,null,2):_=" "+this.formatData(i));let u="";if(n){let{sessionId:d,memorySessionId:nt,correlationId:ot,...D}=n;Object.keys(D).length>0&&(u=` {${Object.entries(D).map(([w,W])=>`${w}=${W}`).join(", ")}}`)}let A=`[${E}] [${s}] [${c}] ${l}${e}${u}${_}`;if(this.logFilePath)try{F(this.logFilePath,A+`
`,"utf8")}catch(d){process.stderr.write(`[LOGGER] Failed to write to log file: ${d}
`)}else process.stderr.write(C+`
`)}else process.stderr.write(A+`
`)}debug(t,r,e,n){this.log(0,t,r,e,n)}info(t,r,e,n){this.log(1,t,r,e,n)}warn(t,r,e,n){this.log(2,t,r,e,n)}error(t,r,e,n){this.log(3,t,r,e,n)}dataIn(t,r,e,n){this.info(t,`\u2192 ${r}`,e,n)}dataOut(t,r,e,n){this.info(t,`\u2190 ${r}`,e,n)}success(t,r,e,n){this.info(t,`\u2713 ${r}`,e,n)}failure(t,r,e,n){this.error(t,`\u2717 ${r}`,e,n)}timing(t,r,e,n){this.info(t,`\u23F1 ${r}`,n,{duration:`${e}ms`})}happyPathError(t,r,e,n,i=""){let l=((new Error().stack||"").split(`
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",u={...e,location:_};return this.warn(t,`[HAPPY-PATH] ${r}`,u,n),i}},a=new M;var m={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*m.WINDOWS_MULTIPLIER):o}import{readFileSync as K,writeFileSync as k,existsSync as P,mkdirSync as G}from"fs";import{join as X,dirname as V}from"path";import{homedir as B}from"os";var I="bugfix,feature,refactor,discovery,decision,change",U="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:X(B(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:U,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!P(t)){let E=this.getAllDefaults();try{let s=V(t);P(s)||G(s,{recursive:!0}),k(t,JSON.stringify(E,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(s){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,s)}return E}let r=K(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{k(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(E){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,E)}}let i={...this.DEFAULTS};for(let E of Object.keys(this.DEFAULTS))n[E]!==void 0&&(i[E]=n[E]);return i}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function y(o={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=o,i=e||"Worker service connection failed.",E=t?` (port ${t})`:"",s=`${i}${E}
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",u={...e,location:_};return this.warn(t,`[HAPPY-PATH] ${r}`,u,n),i}},a=new m;var M={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*M.WINDOWS_MULTIPLIER):o}import{readFileSync as K,writeFileSync as k,existsSync as P,mkdirSync as G}from"fs";import{join as X,dirname as V}from"path";import{homedir as B}from"os";var I="bugfix,feature,refactor,discovery,decision,change",U="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:X(B(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:U,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!P(t)){let E=this.getAllDefaults();try{let s=V(t);P(s)||G(s,{recursive:!0}),k(t,JSON.stringify(E,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(s){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,s)}return E}let r=K(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{k(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(E){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,E)}}let i={...this.DEFAULTS};for(let E of Object.keys(this.DEFAULTS))n[E]!==void 0&&(i[E]=n[E]);return i}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function y(o={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=o,i=e||"Worker service connection failed.",E=t?` (port ${t})`:"",s=`${i}${E}
`;return s+=`To restart the worker:
`,s+=`1. Exit Claude Code completely
@@ -16,4 +16,4 @@ ${i.stack}`:` ${i.message}`:this.getLevel()===0&&typeof i=="object"?_=`
If that doesn't work, try: /troubleshoot`),n&&(s=`Worker Error: ${n}
${s}`),s}var z=L.join(Y(),".claude","plugins","marketplaces","thedotmack"),ht=N(m.HEALTH_CHECK),O=null;function p(){if(O!==null)return O;let o=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(o);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function q(){let o=p();return(await fetch(`http://127.0.0.1:${o}/api/readiness`)).ok}function Q(){let o=L.join(z,"package.json");return JSON.parse(J(o,"utf-8")).version}async function Z(){let o=p(),t=await fetch(`http://127.0.0.1:${o}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function tt(){let o=Q(),t=await Z();o!==t&&a.debug("SYSTEM","Version check",{pluginVersion:o,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function $(){for(let r=0;r<75;r++){try{if(await q()){await tt();return}}catch(e){a.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error(y({port:p(),customPrefix:"Worker did not become ready within 15 seconds."}))}import et from"path";function v(o){if(!o||o.trim()==="")return a.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:o}),"unknown-project";let t=et.basename(o);if(t===""){if(process.platform==="win32"){let e=o.match(/^([A-Z]):\\/i);if(e){let i=`drive-${e[1].toUpperCase()}`;return a.info("PROJECT_NAME","Drive root detected",{cwd:o,projectName:i}),i}}return a.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:o}),"unknown-project"}return t}async function rt(o){if(await $(),!o)throw new Error("newHook requires input");let{session_id:t,cwd:r,prompt:e}=o,n=v(r),i=p();a.debug("HOOK","new-hook: Calling /api/sessions/init",{contentSessionId:t,project:n});let E=await fetch(`http://127.0.0.1:${i}/api/sessions/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:t,project:n,prompt:e})});if(!E.ok)throw new Error(`Session initialization failed: ${E.status}`);let s=await E.json(),c=s.sessionDbId,l=s.promptNumber;if(a.debug("HOOK","new-hook: Received from /api/sessions/init",{sessionDbId:c,promptNumber:l,skipped:s.skipped}),a.debug("HOOK",`[ALIGNMENT] Hook Entry | contentSessionId=${t} | prompt#=${l} | sessionDbId=${c}`),s.skipped&&s.reason==="private"){a.info("HOOK",`INIT_COMPLETE | sessionDbId=${c} | promptNumber=${l} | skipped=true | reason=private`,{sessionId:c}),console.log(T);return}let _=e.startsWith("/")?e.substring(1):e;a.debug("HOOK","new-hook: Calling /sessions/{sessionDbId}/init",{sessionDbId:c,promptNumber:l});let u=await fetch(`http://127.0.0.1:${i}/sessions/${c}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:_,promptNumber:l})});if(!u.ok)throw new Error(`SDK agent start failed: ${u.status}`);a.info("HOOK",`INIT_COMPLETE | sessionDbId=${c} | promptNumber=${l} | project=${n}`,{sessionId:c}),console.log(T)}var A="";b.on("data",o=>A+=o);b.on("end",async()=>{try{let o;try{o=A?JSON.parse(A):void 0}catch(t){throw new Error(`Failed to parse hook input: ${t instanceof Error?t.message:String(t)}`)}await rt(o)}catch(o){a.error("HOOK","new-hook failed",{},o)}finally{process.exit(0)}});
${s}`),s}var z=L.join(Y(),".claude","plugins","marketplaces","thedotmack"),Rt=N(M.HEALTH_CHECK),O=null;function p(){if(O!==null)return O;let o=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(o);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function q(){let o=p();return(await fetch(`http://127.0.0.1:${o}/api/readiness`)).ok}function Q(){let o=L.join(z,"package.json");return JSON.parse(J(o,"utf-8")).version}async function Z(){let o=p(),t=await fetch(`http://127.0.0.1:${o}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function tt(){let o=Q(),t=await Z();o!==t&&a.debug("SYSTEM","Version check",{pluginVersion:o,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function $(){for(let r=0;r<75;r++){try{if(await q()){await tt();return}}catch(e){a.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error(y({port:p(),customPrefix:"Worker did not become ready within 15 seconds."}))}import et from"path";function v(o){if(!o||o.trim()==="")return a.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:o}),"unknown-project";let t=et.basename(o);if(t===""){if(process.platform==="win32"){let e=o.match(/^([A-Z]):\\/i);if(e){let i=`drive-${e[1].toUpperCase()}`;return a.info("PROJECT_NAME","Drive root detected",{cwd:o,projectName:i}),i}}return a.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:o}),"unknown-project"}return t}async function rt(o){if(await $(),!o)throw new Error("newHook requires input");let{session_id:t,cwd:r,prompt:e}=o,n=v(r),i=p();a.debug("HOOK","new-hook: Calling /api/sessions/init",{contentSessionId:t,project:n});let E=await fetch(`http://127.0.0.1:${i}/api/sessions/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:t,project:n,prompt:e})});if(!E.ok)throw new Error(`Session initialization failed: ${E.status}`);let s=await E.json(),c=s.sessionDbId,l=s.promptNumber;if(a.debug("HOOK","new-hook: Received from /api/sessions/init",{sessionDbId:c,promptNumber:l,skipped:s.skipped}),a.debug("HOOK",`[ALIGNMENT] Hook Entry | contentSessionId=${t} | prompt#=${l} | sessionDbId=${c}`),s.skipped&&s.reason==="private"){a.info("HOOK",`INIT_COMPLETE | sessionDbId=${c} | promptNumber=${l} | skipped=true | reason=private`,{sessionId:c}),console.log(T);return}let _=e.startsWith("/")?e.substring(1):e;a.debug("HOOK","new-hook: Calling /sessions/{sessionDbId}/init",{sessionDbId:c,promptNumber:l});let u=await fetch(`http://127.0.0.1:${i}/sessions/${c}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:_,promptNumber:l})});if(!u.ok)throw new Error(`SDK agent start failed: ${u.status}`);a.info("HOOK",`INIT_COMPLETE | sessionDbId=${c} | promptNumber=${l} | project=${n}`,{sessionId:c}),console.log(T)}var C="";b.on("data",o=>C+=o);b.on("end",async()=>{try{let o;try{o=C?JSON.parse(C):void 0}catch(t){throw new Error(`Failed to parse hook input: ${t instanceof Error?t.message:String(t)}`)}await rt(o)}catch(o){a.error("HOOK","new-hook failed",{},o)}finally{process.exit(0)}});

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bun
import{stdin as v}from"process";var U=JSON.stringify({continue:!0,suppressOutput:!0});import{appendFileSync as H,existsSync as d,mkdirSync as W,readFileSync as b}from"fs";import{join as T}from"path";import{homedir as x}from"os";var f=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(f||{}),R=T(x(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(R,"logs");d(t)||W(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(R,"settings.json");if(d(t)){let r=b(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=f[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
import{stdin as v}from"process";var d=JSON.stringify({continue:!0,suppressOutput:!0});import{appendFileSync as H,existsSync as U,mkdirSync as W,readFileSync as b}from"fs";import{join as T}from"path";import{homedir as x}from"os";var f=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(f||{}),R=T(x(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(R,"logs");U(t)||W(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(R,"settings.json");if(U(t)){let r=b(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=f[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),E=String(t.getMinutes()).padStart(2,"0"),i=String(t.getSeconds()).padStart(2,"0"),a=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${o}:${E}:${i}.${a}`}log(t,r,e,n,o){if(t<this.getLevel())return;this.ensureLogFileInitialized();let E=this.formatTimestamp(new Date),i=f[t].padEnd(5),a=r.padEnd(6),l="";n?.correlationId?l=`[${n.correlationId}] `:n?.sessionId&&(l=`[session-${n.sessionId}] `);let c="";o!=null&&(o instanceof Error?c=this.getLevel()===0?`
${o.message}
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?c=`
@@ -16,4 +16,4 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?c=`
If that doesn't work, try: /troubleshoot`),n&&(i=`Worker Error: ${n}
${i}`),i}var J=L.join(B(),".claude","plugins","marketplaces","thedotmack"),mt=I(p.HEALTH_CHECK),S=null;function u(){if(S!==null)return S;let s=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(s);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}async function z(){let s=u();return(await fetch(`http://127.0.0.1:${s}/api/readiness`)).ok}function q(){let s=L.join(J,"package.json");return JSON.parse(Y(s,"utf-8")).version}async function Q(){let s=u(),t=await fetch(`http://127.0.0.1:${s}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function Z(){let s=q(),t=await Q();s!==t&&_.debug("SYSTEM","Version check",{pluginVersion:s,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function k(){for(let r=0;r<75;r++){try{if(await z()){await Z();return}}catch(e){_.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error($({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}async function tt(s){if(await k(),!s)throw new Error("saveHook requires input");let{session_id:t,cwd:r,tool_name:e,tool_input:n,tool_response:o}=s,E=u(),i=_.formatTool(e,n);if(_.dataIn("HOOK",`PostToolUse: ${i}`,{workerPort:E}),!r)throw new Error(`Missing cwd in PostToolUse hook input for session ${t}, tool ${e}`);let a=await fetch(`http://127.0.0.1:${E}/api/sessions/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:t,tool_name:e,tool_input:n,tool_response:o,cwd:r})});if(!a.ok)throw new Error(`Observation storage failed: ${a.status}`);_.debug("HOOK","Observation sent successfully",{toolName:e}),console.log(U)}var A="";v.on("data",s=>A+=s);v.on("end",async()=>{try{let s;try{s=A?JSON.parse(A):void 0}catch(t){throw new Error(`Failed to parse hook input: ${t instanceof Error?t.message:String(t)}`)}await tt(s)}catch(s){_.error("HOOK","save-hook failed",{},s)}finally{process.exit(0)}});
${i}`),i}var J=L.join(B(),".claude","plugins","marketplaces","thedotmack"),mt=I(p.HEALTH_CHECK),S=null;function u(){if(S!==null)return S;let s=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(s);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}async function z(){let s=u();return(await fetch(`http://127.0.0.1:${s}/api/readiness`)).ok}function q(){let s=L.join(J,"package.json");return JSON.parse(Y(s,"utf-8")).version}async function Q(){let s=u(),t=await fetch(`http://127.0.0.1:${s}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function Z(){let s=q(),t=await Q();s!==t&&_.debug("SYSTEM","Version check",{pluginVersion:s,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function k(){for(let r=0;r<75;r++){try{if(await z()){await Z();return}}catch(e){_.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error($({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}async function tt(s){if(await k(),!s)throw new Error("saveHook requires input");let{session_id:t,cwd:r,tool_name:e,tool_input:n,tool_response:o}=s,E=u(),i=_.formatTool(e,n);if(_.dataIn("HOOK",`PostToolUse: ${i}`,{workerPort:E}),!r)throw new Error(`Missing cwd in PostToolUse hook input for session ${t}, tool ${e}`);let a=await fetch(`http://127.0.0.1:${E}/api/sessions/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:t,tool_name:e,tool_input:n,tool_response:o,cwd:r})});if(!a.ok)throw new Error(`Observation storage failed: ${a.status}`);_.debug("HOOK","Observation sent successfully",{toolName:e}),console.log(d)}var A="";v.on("data",s=>A+=s);v.on("end",async()=>{try{let s;try{s=A?JSON.parse(A):void 0}catch(t){throw new Error(`Failed to parse hook input: ${t instanceof Error?t.message:String(t)}`)}await tt(s)}catch(s){_.error("HOOK","save-hook failed",{},s)}finally{process.exit(0)}});

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bun
import{stdin as v}from"process";var T=JSON.stringify({continue:!0,suppressOutput:!0});import{appendFileSync as H,existsSync as R,mkdirSync as W,readFileSync as b}from"fs";import{join as S}from"path";import{homedir as G}from"os";var p=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(p||{}),U=S(G(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=S(U,"logs");R(t)||W(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=S(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=S(U,"settings.json");if(R(t)){let r=b(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=p[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
import{stdin as v}from"process";var T=JSON.stringify({continue:!0,suppressOutput:!0});import{appendFileSync as H,existsSync as R,mkdirSync as W,readFileSync as b}from"fs";import{join as O}from"path";import{homedir as G}from"os";var p=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(p||{}),U=O(G(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=O(U,"logs");R(t)||W(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=O(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=O(U,"settings.json");if(R(t)){let r=b(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=p[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),E=String(t.getMinutes()).padStart(2,"0"),i=String(t.getSeconds()).padStart(2,"0"),_=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${o}:${E}:${i}.${_}`}log(t,r,e,n,o){if(t<this.getLevel())return;this.ensureLogFileInitialized();let E=this.formatTimestamp(new Date),i=p[t].padEnd(5),_=r.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let l="";o!=null&&(o instanceof Error?l=this.getLevel()===0?`
${o.message}
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?l=`
@@ -16,7 +16,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?l=`
If that doesn't work, try: /troubleshoot`),n&&(i=`Worker Error: ${n}
${i}`),i}var z=L.join(Y(),".claude","plugins","marketplaces","thedotmack"),Ut=h(m.HEALTH_CHECK),O=null;function u(){if(O!==null)return O;let s=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(s);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function q(){let s=u();return(await fetch(`http://127.0.0.1:${s}/api/readiness`)).ok}function Q(){let s=L.join(z,"package.json");return JSON.parse(J(s,"utf-8")).version}async function Z(){let s=u(),t=await fetch(`http://127.0.0.1:${s}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function tt(){let s=Q(),t=await Z();s!==t&&c.debug("SYSTEM","Version check",{pluginVersion:s,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function P(){for(let r=0;r<75;r++){try{if(await q()){await tt();return}}catch(e){c.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error(k({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}import{readFileSync as et,existsSync as rt}from"fs";function w(s,t,r=!1){if(!s||!rt(s))throw new Error(`Transcript path missing or file does not exist: ${s}`);let e=et(s,"utf-8").trim();if(!e)throw new Error(`Transcript file exists but is empty: ${s}`);let n=e.split(`
${i}`),i}var z=L.join(Y(),".claude","plugins","marketplaces","thedotmack"),Ut=h(m.HEALTH_CHECK),S=null;function u(){if(S!==null)return S;let s=L.join(g.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=g.loadFromFile(s);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}async function q(){let s=u();return(await fetch(`http://127.0.0.1:${s}/api/readiness`)).ok}function Q(){let s=L.join(z,"package.json");return JSON.parse(J(s,"utf-8")).version}async function Z(){let s=u(),t=await fetch(`http://127.0.0.1:${s}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function tt(){let s=Q(),t=await Z();s!==t&&c.debug("SYSTEM","Version check",{pluginVersion:s,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function P(){for(let r=0;r<75;r++){try{if(await q()){await tt();return}}catch(e){c.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error(k({port:u(),customPrefix:"Worker did not become ready within 15 seconds."}))}import{readFileSync as et,existsSync as rt}from"fs";function w(s,t,r=!1){if(!s||!rt(s))throw new Error(`Transcript path missing or file does not exist: ${s}`);let e=et(s,"utf-8").trim();if(!e)throw new Error(`Transcript file exists but is empty: ${s}`);let n=e.split(`
`),o=!1;for(let E=n.length-1;E>=0;E--){let i=JSON.parse(n[E]);if(i.type===t&&(o=!0,i.message?.content)){let _="",a=i.message.content;if(typeof a=="string")_=a;else if(Array.isArray(a))_=a.filter(l=>l.type==="text").map(l=>l.text).join(`
`);else throw new Error(`Unknown message content format in transcript. Type: ${typeof a}`);return r&&(_=_.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g,""),_=_.replace(/\n{3,}/g,`

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bun
import{basename as tt}from"path";import L from"path";import{homedir as Y}from"os";import{readFileSync as B}from"fs";import{appendFileSync as W,existsSync as U,mkdirSync as b,readFileSync as x}from"fs";import{join as T}from"path";import{homedir as G}from"os";var S=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(S||{}),R=T(G(),".claude-mem"),M=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(R,"logs");U(t)||b(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(R,"settings.json");if(U(t)){let r=x(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=S[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),E=String(t.getMinutes()).padStart(2,"0"),s=String(t.getSeconds()).padStart(2,"0"),g=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${o}:${E}:${s}.${g}`}log(t,r,e,n,o){if(t<this.getLevel())return;this.ensureLogFileInitialized();let E=this.formatTimestamp(new Date),s=S[t].padEnd(5),g=r.padEnd(6),_="";n?.correlationId?_=`[${n.correlationId}] `:n?.sessionId&&(_=`[session-${n.sessionId}] `);let a="";o!=null&&(o instanceof Error?a=this.getLevel()===0?`
import{basename as Z}from"path";import p from"path";import{homedir as j}from"os";import{readFileSync as B}from"fs";import{appendFileSync as w,existsSync as R,mkdirSync as W,readFileSync as b}from"fs";import{join as T}from"path";import{homedir as x}from"os";var M=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(M||{}),U=T(x(),".claude-mem"),S=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let t=T(U,"logs");R(t)||W(t,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=T(t,`claude-mem-${r}.log`)}catch(t){console.error("[LOGGER] Failed to initialize log file:",t),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let t=T(U,"settings.json");if(R(t)){let r=b(t,"utf-8"),n=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=M[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(t,r){return`obs-${t}-${r}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.getLevel()===0?`${t.message}
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let r=Object.keys(t);return r.length===0?"{}":r.length<=3?JSON.stringify(t):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,r){if(!r)return t;let e=r;if(typeof r=="string")try{e=JSON.parse(r)}catch{e=r}if(t==="Bash"&&e.command)return`${t}(${e.command})`;if(e.file_path)return`${t}(${e.file_path})`;if(e.notebook_path)return`${t}(${e.notebook_path})`;if(t==="Glob"&&e.pattern)return`${t}(${e.pattern})`;if(t==="Grep"&&e.pattern)return`${t}(${e.pattern})`;if(e.url)return`${t}(${e.url})`;if(e.query)return`${t}(${e.query})`;if(t==="Task"){if(e.subagent_type)return`${t}(${e.subagent_type})`;if(e.description)return`${t}(${e.description})`}return t==="Skill"&&e.skill?`${t}(${e.skill})`:t==="LSP"&&e.operation?`${t}(${e.operation})`:t}formatTimestamp(t){let r=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),E=String(t.getMinutes()).padStart(2,"0"),s=String(t.getSeconds()).padStart(2,"0"),g=String(t.getMilliseconds()).padStart(3,"0");return`${r}-${e}-${n} ${o}:${E}:${s}.${g}`}log(t,r,e,n,o){if(t<this.getLevel())return;this.ensureLogFileInitialized();let E=this.formatTimestamp(new Date),s=M[t].padEnd(5),g=r.padEnd(6),_="";n?.correlationId?_=`[${n.correlationId}] `:n?.sessionId&&(_=`[session-${n.sessionId}] `);let a="";o!=null&&(o instanceof Error?a=this.getLevel()===0?`
${o.message}
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?a=`
`+JSON.stringify(o,null,2):a=" "+this.formatData(o));let u="";if(n){let{sessionId:D,memorySessionId:nt,correlationId:ot,...m}=n;Object.keys(m).length>0&&(u=` {${Object.entries(m).map(([F,w])=>`${F}=${w}`).join(", ")}}`)}let C=`[${E}] [${s}] [${g}] ${_}${e}${u}${a}`;if(this.logFilePath)try{W(this.logFilePath,C+`
`+JSON.stringify(o,null,2):a=" "+this.formatData(o));let u="";if(n){let{sessionId:D,memorySessionId:rt,correlationId:nt,...m}=n;Object.keys(m).length>0&&(u=` {${Object.entries(m).map(([P,F])=>`${P}=${F}`).join(", ")}}`)}let A=`[${E}] [${s}] [${g}] ${_}${e}${u}${a}`;if(this.logFilePath)try{w(this.logFilePath,A+`
`,"utf8")}catch(D){process.stderr.write(`[LOGGER] Failed to write to log file: ${D}
`)}else process.stderr.write(C+`
`)}else process.stderr.write(A+`
`)}debug(t,r,e,n){this.log(0,t,r,e,n)}info(t,r,e,n){this.log(1,t,r,e,n)}warn(t,r,e,n){this.log(2,t,r,e,n)}error(t,r,e,n){this.log(3,t,r,e,n)}dataIn(t,r,e,n){this.info(t,`\u2192 ${r}`,e,n)}dataOut(t,r,e,n){this.info(t,`\u2190 ${r}`,e,n)}success(t,r,e,n){this.info(t,`\u2713 ${r}`,e,n)}failure(t,r,e,n){this.error(t,`\u2717 ${r}`,e,n)}timing(t,r,e,n){this.info(t,`\u23F1 ${r}`,n,{duration:`${e}ms`})}happyPathError(t,r,e,n,o=""){let _=((new Error().stack||"").split(`
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=_?`${_[1].split("/").pop()}:${_[2]}`:"unknown",u={...e,location:a};return this.warn(t,`[HAPPY-PATH] ${r}`,u,n),o}},f=new M;var p={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5},d={SUCCESS:0,FAILURE:1,USER_MESSAGE_ONLY:3};function h(i){return process.platform==="win32"?Math.round(i*p.WINDOWS_MULTIPLIER):i}import{readFileSync as H,writeFileSync as y,existsSync as $,mkdirSync as K}from"fs";import{join as X,dirname as V}from"path";import{homedir as j}from"os";var I="bugfix,feature,refactor,discovery,decision,change",N="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:X(j(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:N,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!$(t)){let E=this.getAllDefaults();try{let s=V(t);$(s)||K(s,{recursive:!0}),y(t,JSON.stringify(E,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(s){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,s)}return E}let r=H(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{y(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(E){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,E)}}let o={...this.DEFAULTS};for(let E of Object.keys(this.DEFAULTS))n[E]!==void 0&&(o[E]=n[E]);return o}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function k(i={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=i,o=e||"Worker service connection failed.",E=t?` (port ${t})`:"",s=`${o}${E}
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=_?`${_[1].split("/").pop()}:${_[2]}`:"unknown",u={...e,location:a};return this.warn(t,`[HAPPY-PATH] ${r}`,u,n),o}},f=new S;var L={DEFAULT:3e5,HEALTH_CHECK:3e4,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:300,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function d(i){return process.platform==="win32"?Math.round(i*L.WINDOWS_MULTIPLIER):i}import{readFileSync as G,writeFileSync as N,existsSync as y,mkdirSync as H}from"fs";import{join as K,dirname as X}from"path";import{homedir as V}from"os";var h="bugfix,feature,refactor,discovery,decision,change",I="how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off";var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:K(V(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:h,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:I,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return this.DEFAULTS[t]}static getInt(t){let r=this.get(t);return parseInt(r,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){try{if(!y(t)){let E=this.getAllDefaults();try{let s=X(t);y(s)||H(s,{recursive:!0}),N(t,JSON.stringify(E,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",t)}catch(s){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",t,s)}return E}let r=G(t,"utf-8"),e=JSON.parse(r),n=e;if(e.env&&typeof e.env=="object"){n=e.env;try{N(t,JSON.stringify(n,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",t)}catch(E){console.warn("[SETTINGS] Failed to auto-migrate settings file:",t,E)}}let o={...this.DEFAULTS};for(let E of Object.keys(this.DEFAULTS))n[E]!==void 0&&(o[E]=n[E]);return o}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",t,r),this.getAllDefaults()}}};function $(i={}){let{port:t,includeSkillFallback:r=!1,customPrefix:e,actualError:n}=i,o=e||"Worker service connection failed.",E=t?` (port ${t})`:"",s=`${o}${E}
`;return s+=`To restart the worker:
`,s+=`1. Exit Claude Code completely
@@ -16,15 +16,15 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?a=`
If that doesn't work, try: /troubleshoot`),n&&(s=`Worker Error: ${n}
${s}`),s}var J=L.join(Y(),".claude","plugins","marketplaces","thedotmack"),Ut=h(p.HEALTH_CHECK),O=null;function c(){if(O!==null)return O;let i=L.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(i);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function z(){let i=c();return(await fetch(`http://127.0.0.1:${i}/api/readiness`)).ok}function q(){let i=L.join(J,"package.json");return JSON.parse(B(i,"utf-8")).version}async function Q(){let i=c(),t=await fetch(`http://127.0.0.1:${i}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function Z(){let i=q(),t=await Q();i!==t&&f.debug("SYSTEM","Version check",{pluginVersion:i,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function v(){for(let r=0;r<75;r++){try{if(await z()){await Z();return}}catch(e){f.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error(k({port:c(),customPrefix:"Worker did not become ready within 15 seconds."}))}await v();var P=c(),et=tt(process.cwd()),A=await fetch(`http://127.0.0.1:${P}/api/context/inject?project=${encodeURIComponent(et)}&colors=true`,{method:"GET"});if(!A.ok)throw new Error(`Failed to fetch context: ${A.status}`);var rt=await A.text();console.error(`
${s}`),s}var Y=p.join(j(),".claude","plugins","marketplaces","thedotmack"),mt=d(L.HEALTH_CHECK),O=null;function c(){if(O!==null)return O;let i=p.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(i);return O=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),O}async function J(){let i=c();return(await fetch(`http://127.0.0.1:${i}/api/readiness`)).ok}function z(){let i=p.join(Y,"package.json");return JSON.parse(B(i,"utf-8")).version}async function q(){let i=c(),t=await fetch(`http://127.0.0.1:${i}/api/version`);if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function Q(){let i=z(),t=await q();i!==t&&f.debug("SYSTEM","Version check",{pluginVersion:i,workerVersion:t,note:"Mismatch will be auto-restarted by worker-service start command"})}async function k(){for(let r=0;r<75;r++){try{if(await J()){await Q();return}}catch(e){f.debug("SYSTEM","Worker health check failed, will retry",{attempt:r+1,maxRetries:75,error:e instanceof Error?e.message:String(e)})}await new Promise(e=>setTimeout(e,200))}throw new Error($({port:c(),customPrefix:"Worker did not become ready within 15 seconds."}))}await k();var v=c(),tt=Z(process.cwd()),C=await fetch(`http://127.0.0.1:${v}/api/context/inject?project=${encodeURIComponent(tt)}&colors=true`,{method:"GET"});if(!C.ok)throw new Error(`Failed to fetch context: ${C.status}`);var et=await C.text();console.error(`
\u{1F4DD} Claude-Mem Context Loaded
\u2139\uFE0F Note: This appears as stderr but is informational only
`+rt+`
`+et+`
\u{1F4A1} New! Wrap all or part of any message with <private> ... </private> to prevent storing sensitive information in your observation history.
\u{1F4AC} Community https://discord.gg/J4wttp9vDu
\u{1F4FA} Watch live in browser http://localhost:${P}/
`);process.exit(d.USER_MESSAGE_ONLY);
\u{1F4FA} Watch live in browser http://localhost:${v}/
`);process.exit(1);

File diff suppressed because one or more lines are too long

View File

@@ -3,13 +3,6 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 24, 2025
**viewer-bundle.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32379 | 9:10 PM | ✅ | Built and deployed claude-mem v8.0.6 to marketplace | ~370 |
### Dec 25, 2025
**viewer-bundle.js**
@@ -22,7 +15,6 @@
| #32600 | 8:42 PM | 🔵 | Identified potential UI element for billing toggle | ~146 |
| #32559 | 8:18 PM | 🔵 | Listed files changed in the current branch | ~169 |
| #32458 | 5:42 PM | ✅ | Rebuilt and synchronized plugin files after merge | ~286 |
| #32440 | 3:44 PM | ✅ | Project build completed for version 8.1.0 | ~335 |
### Dec 26, 2025
@@ -134,4 +126,12 @@
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
### Jan 7, 2026
**viewer-bundle.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38186 | 7:33 PM | 🟣 | Claude-mem plugin v9.0.0 built and deployed to marketplace | ~327 |
| #38120 | 5:46 PM | 🔴 | Rebuilt all plugin hooks and worker service | ~278 |
</claude-mem-context>

View File

@@ -3,72 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 15, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27158 | 8:08 PM | 🔵 | Complete API Key Authentication Flow Traced Through System | ~460 |
### Dec 16, 2025
**collector.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27823 | 6:56 PM | 🔵 | Bug Report System Reads PID File for Diagnostics | ~264 |
### Dec 20, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30253 | 3:17 PM | 🔵 | Agent SDK Integration Throughout Codebase | ~402 |
### Dec 21, 2025
**cli.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31603 | 8:21 PM | 🔵 | Complete Console.* Statement Audit Across Codebase | ~813 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31601 | 8:19 PM | 🔵 | 215 console logging statements in TypeScript utility scripts | ~501 |
### Dec 30, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34502 | 2:31 PM | ✅ | Updated Bug Report Script Import to V2 API | ~292 |
### Dec 31, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34572 | 2:36 PM | ⚖️ | Comprehensive Post-Mortem Document Created | ~692 |
| #34571 | 2:35 PM | ⚖️ | Post-Mortem Analysis Identifies Scope Confusion as Root Failure Cause | ~599 |
| #34570 | " | 🔵 | Root Cause Identified: Utility Scripts Never Fixed Despite Phase 4 Review | ~513 |
| #34569 | " | 🔵 | Bug Report Script Shows Same systemPrompt Error and Unsafe Result Access | ~443 |
### Jan 1, 2026
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35288 | 1:22 PM | 🔵 | Bug Report Generation Tool Using Agent SDK | ~501 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**collector.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37990 | 9:00 PM | 🔵 | CLAUDE_MEM_WORKER_HOST setting used across 19 files | ~289 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,11 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37391 | 12:48 AM | ✅ | Staged 23 CLAUDE.md files with mix of new and modified content | ~400 |
| #37390 | 12:47 AM | ✅ | Regenerated 23 CLAUDE.md files in budapest workspace | ~365 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,147 +3,98 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 30, 2025
### Dec 9, 2025
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34440 | 2:16 PM | 🔵 | TypeScript type errors identified across multiple components | ~328 |
| #23126 | 6:40 PM | | Removed SKIP_TOOLS Check from saveHook Function | ~288 |
| #23125 | " | 🔵 | SKIP_TOOLS Reference Still Present in saveHook Function | ~224 |
| #23124 | " | ✅ | Removed SKIP_TOOLS Constant from save-hook.ts | ~297 |
| #23123 | 6:39 PM | 🔵 | Current SKIP_TOOLS Implementation in save-hook.ts | ~397 |
| #23122 | " | 🔴 | Hardened Spinner Stop Mechanism with Timeout and Logging | ~361 |
| #23121 | " | 🔵 | Current Spinner Stop Implementation in summary-hook.ts | ~348 |
| #23118 | 6:38 PM | ✅ | Phase 6: StopInput Interface Type Safety Restored | ~248 |
| #23117 | 6:37 PM | ✅ | Phase 6: PostToolUseInput Interface Type Safety Restored | ~222 |
| #23116 | " | ✅ | Phase 6: UserPromptSubmitInput Interface Type Safety Restored | ~216 |
| #23115 | " | ✅ | Phase 6: SessionStartInput Interface Type Safety Restored | ~341 |
| #23114 | " | 🔵 | Current State of context-hook.ts Interface | ~409 |
| #23113 | " | 🔵 | Current State of summary-hook.ts Interface and Spinner Stop | ~397 |
| #23112 | " | 🔵 | Current State of save-hook.ts Interface and SKIP_TOOLS | ~395 |
| #23111 | " | 🔵 | Current State of new-hook.ts Interface | ~381 |
| #23076 | 6:27 PM | ✅ | Added Comment Explaining Exit Code 3 in user-message-hook.ts | ~245 |
| #23075 | 6:26 PM | ✅ | Deleted Expired Announcement Code from user-message-hook.ts | ~354 |
| #23074 | " | ✅ | Replaced Verbose Manual Mode Help with Error in cleanup-hook.ts | ~222 |
| #23073 | " | ✅ | Removed cwd from cleanup-hook Debug Logging | ~177 |
| #23072 | " | ✅ | Simplified SessionEndInput Interface in cleanup-hook.ts | ~236 |
### Dec 10, 2025
**summary-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34393 | 1:41 PM | 🔵 | Stop Hook (summary-hook.ts) Only Requests Summary, No Process Cleanup | ~375 |
| #23407 | 2:14 PM | 🔵 | New Hook Implementation Structure | ~264 |
### Dec 31, 2025
### Dec 13, 2025
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34675 | 3:37 PM | 🔵 | API Endpoint /api/sessions/init Expects contentSessionId Parameter | ~401 |
| #34674 | " | 🔵 | Source Hook Files Use contentSessionId Parameter | ~327 |
| #34602 | 2:56 PM | 🔵 | New Hook Architecture: Session Initialization and Privacy Filtering | ~385 |
| #25389 | 9:30 PM | 🔴 | Save Hook Error Logging Enhanced With Tool Context | ~361 |
| #25388 | " | 🔴 | New Hook Now Logs SDK Agent Start Errors | ~344 |
| #25387 | 9:29 PM | 🔴 | New Hook Now Logs Session Initialization Errors | ~350 |
| #25386 | " | 🔴 | Context Hook Now Logs Error Text Before Throwing | ~338 |
| #25385 | " | ✅ | Added Logger Import to New Hook | ~249 |
| #25384 | " | ✅ | Added Logger Import to Context Hook | ~223 |
| #25383 | " | 🔵 | New Hook Has Two Silent Failure Points | ~392 |
| #25382 | 9:28 PM | 🔵 | Save Hook Has Partial Error Logging | ~351 |
| #25381 | " | 🔵 | Summary Hook Has Partial Error Logging | ~345 |
| #25380 | " | 🔵 | Context Hook Silent Failure Pattern Confirmed | ~354 |
### Dec 14, 2025
**context-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34631 | 3:02 PM | 🟣 | Context-Preservation Workflow Design Documents Created | ~729 |
| #26730 | 11:24 PM | 🔵 | Context Hook TypeScript Source Shows EnsureWorkerRunning as First Action | ~441 |
| #26729 | " | 🔵 | Context Hook TypeScript Source Calls ensureWorkerRunning Before API Requests | ~411 |
| #26260 | 8:32 PM | 🔵 | User Message Hook Calls Context Inject with colors=true Parameter | ~300 |
| #26244 | 8:29 PM | 🔵 | Context Hook Delegates to Worker API Context Endpoint | ~260 |
| #25692 | 4:24 PM | 🔵 | Summary hook extracts last user and assistant messages from transcript file before sending to worker | ~465 |
### Jan 1, 2026
### Dec 17, 2025
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35287 | 1:22 PM | 🔵 | SDKAgent Resume Logic Analysis - Two-Stage Session ID System | ~517 |
| #35284 | " | 🔵 | New Hook Session Initialization Flow | ~631 |
| #35221 | 1:11 PM | 🔵 | New-hook workflow: Two-phase session initialization | ~477 |
| #35201 | 1:07 PM | 🔵 | New Hook receives and processes cwd parameter | ~303 |
| #28449 | 4:23 PM | 🔵 | New Hook Session Initialization Flow | ~385 |
### Dec 19, 2025
**context-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35206 | 1:08 PM | 🔵 | context-hook.ts falls back to process.cwd() when cwd missing | ~311 |
| #30105 | 8:11 PM | 🔵 | Hook Response Utility Standardizes Hook Output Format | ~387 |
| #30103 | 8:10 PM | 🔵 | Context Hook Injects Mode-Based Memory Context During SessionStart | ~460 |
### Dec 20, 2025
**save-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35204 | 1:07 PM | 🔵 | PostToolUse hook validates cwd as required field | ~301 |
| #31085 | 7:59 PM | 🔵 | Summary Hook Uses session_id from Hook Input | ~315 |
### Jan 2, 2026
### Dec 27, 2025
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35997 | 5:32 PM | 🟣 | Session Alignment Logging Implemented Across Hook, HTTP, and SDK Layers | ~342 |
| #35977 | 4:48 PM | 🔵 | Existing alignment logging infrastructure found | ~353 |
| #35970 | 4:47 PM | 🔵 | Session ID Logging Distribution Across Codebase | ~485 |
| #35964 | 4:45 PM | 🔵 | Session Initialization Two-Stage API Pattern | ~468 |
| #35954 | 4:43 PM | 🔵 | New Hook Session Initialization Flow | ~393 |
| #35893 | 2:48 PM | 🔵 | New Hook Initializes Session And Starts SDK Agent Without Exit Code | ~382 |
| #35833 | 2:29 PM | 🔵 | New Hook Starts Memory Agent Asynchronously | ~404 |
| #33216 | 9:07 PM | 🔵 | UserPromptSubmit Hook (new-hook.ts) Initializes Session and Starts SDK Agent via Two HTTP Endpoints | ~735 |
| #33211 | 9:04 PM | 🔵 | User Message Hook Displays Context Info via stderr in Parallel with Context Injection | ~476 |
| #33210 | 9:03 PM | 🔵 | Summary Hook (summary-hook.ts) Extracts Messages and Triggers Summarization | ~479 |
| #33209 | " | 🔵 | SessionStart Hook (context-hook.ts) Fetches Context Injection via HTTP | ~520 |
### Jan 7, 2026
**context-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35958 | 4:44 PM | 🔵 | Context Hook Session Context Injection | ~379 |
| #35894 | 2:48 PM | 🔵 | Context Hook Explicitly Exits With Code 0 On Success | ~355 |
| #35837 | 2:30 PM | 🔵 | Context Hook Returns Synchronously with Explicit Exit | ~413 |
**save-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35956 | 4:43 PM | 🔵 | Save Hook Tool Observation Storage | ~380 |
| #35899 | 2:48 PM | 🔵 | Save Hook Sends Observations Without Explicit Exit Code | ~387 |
| #35869 | 2:36 PM | 🔴 | Save Hook Entry Point Lacks Error Handling Around Async Call | ~448 |
| #35835 | 2:30 PM | 🔵 | Save Hook Uses Fire-and-Forget for Observations | ~394 |
**user-message-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35955 | 4:43 PM | 🔵 | User Message Hook Context Display Mechanism | ~369 |
| #35888 | 2:47 PM | 🔵 | User Message Hook Exits With USER_MESSAGE_ONLY Code | ~313 |
| #35831 | 2:29 PM | 🔵 | User Message Hook Exits with Special Exit Code | ~348 |
**hook-response.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35953 | 4:43 PM | 🔵 | Standard Hook Response Protocol | ~253 |
| #35950 | 4:42 PM | 🔵 | Hook System Architecture Discovery | ~254 |
| #35891 | 2:47 PM | 🔵 | STANDARD_HOOK_RESPONSE Signals Continue And Suppress Output | ~333 |
**summary-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #35889 | 2:47 PM | 🔵 | Summary Hook Outputs STANDARD_HOOK_RESPONSE On Success And Error | ~358 |
| #35829 | 2:29 PM | 🔵 | Summary Hook Uses Fire-and-Forget HTTP Pattern | ~385 |
| #35770 | 1:23 PM | ✅ | Last User Message Field Removed Across 11 Files in Codebase | ~374 |
| #35747 | 1:18 PM | 🔴 | Removed Incorrect last_user_message Extraction from Summary Hook | ~382 |
| #35734 | 1:11 PM | 🔵 | Summary Hook Extracts Last User and Assistant Messages from Transcript | ~383 |
| #35733 | " | 🔵 | Located last_user_message usage across codebase | ~333 |
### Jan 3, 2026
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36296 | 8:04 PM | 🔵 | TypeScript Compilation Check: Pre-Existing Errors Unrelated to Refactoring | ~621 |
| #36112 | 3:44 PM | 🔵 | New Hook Architecture and Session Initialization Flow | ~412 |
### Jan 5, 2026
**save-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38081 | 9:55 PM | 🔵 | Save Hook - Pure HTTP Client with No Database Dependencies | ~206 |
| #37626 | 5:35 PM | 🔵 | FormatTool Function Usage Across Codebase | ~493 |
| #37540 | 4:46 PM | 🔵 | save-hook.ts First formatTool Call Point in Observation Pipeline | ~416 |
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**context-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38076 | 9:53 PM | 🟣 | Worktree-Aware Project Filtering for Unified Timeline Context | ~578 |
**new-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38000 | 9:02 PM | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
| #37999 | " | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
**hook-response.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37554 | 4:48 PM | 🔵 | Standard Hook Response Protocol for Claude Code | ~387 |
### Jan 6, 2026
**context-hook.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
| #38235 | 7:42 PM | | Deprecated User Message Hook Source File | ~399 |
| #38176 | 7:26 PM | ⚖️ | Plan Created to Merge User Message into Context Hook JSON Output | ~536 |
| #38175 | " | 🔵 | Complete Claude-Mem Hook Output Architecture Documented | ~530 |
| #38174 | " | 🔵 | UserPromptSubmit Hook Initializes Sessions and Strips Slash Commands | ~480 |
| #38173 | 7:25 PM | 🔵 | Standard Hook Response Pattern for Non-SessionStart Hooks | ~343 |
| #38172 | 7:22 PM | 🔵 | Claude Code Hook Output Architecture Clarified - Exit Code Pattern is Correct for User-Only Display | ~523 |
| #38170 | 7:21 PM | 🔵 | User-Message-Hook TypeScript Source Shows Exit Code 1 Strategy for User-Only Display | ~203 |
</claude-mem-context>

View File

@@ -1,15 +1,20 @@
/**
* User Message Hook - SessionStart
* Displays context information to the user via stderr
*
* This hook runs in parallel with context-hook to show users what context
* has been loaded into their session. Uses stderr as the communication channel
* since it's currently the only way to display messages in Claude Code UI.
* @deprecated This hook is no longer used as of Claude Code 2.1.0 (ultrathink update).
* SessionStart hooks no longer display any user-visible messages in the Claude Code UI.
* Context is still injected via hookSpecificOutput.additionalContext in context-hook.ts,
* but users don't see any startup output.
*
* This file is kept for reference but is not registered in hooks.json.
*
* Historical behavior:
* - Displayed context information to the user via stderr
* - Ran in parallel with context-hook to show users what context was loaded
* - Used stderr + exit code 1 to display to user only without adding to Claude's context
*/
import { basename } from "path";
import { ensureWorkerRunning, getWorkerPort } from "../shared/worker-utils.js";
import { HOOK_EXIT_CODES } from "../shared/hook-constants.js";
import { logger } from "../utils/logger.js";
// Ensure worker is running
await ensureWorkerRunning();
@@ -39,4 +44,4 @@ console.error(
`\n📺 Watch live in browser http://localhost:${port}/\n`
);
process.exit(HOOK_EXIT_CODES.USER_MESSAGE_ONLY);
process.exit(1); // Exit code 1 for SessionStart = show stderr to user only

View File

@@ -3,139 +3,19 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 22, 2025
**SDKAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31951 | 8:17 PM | 🟣 | Mode System with Inheritance and Multilingual Support | ~776 |
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31891 | 7:17 PM | 🔴 | Migration des prompts de résumé vers les fichiers de modes pour le support multilingue | ~474 |
| #31890 | " | 🔵 | Modifications en cours sur les fichiers de modes multilingues et le système de prompts | ~325 |
| #31872 | 7:04 PM | 🔄 | Externalisation des prompts de résumé codés en dur | ~378 |
| #31868 | 7:03 PM | 🔵 | サマリープロンプトのハードコーディング箇所の特定 | ~193 |
| #31829 | 6:28 PM | 🔄 | Removed languageNote usage from continuation observation XML template | ~90 |
| #31828 | " | 🔄 | Removed languageNote variable from buildContinuationPrompt | ~199 |
| #31827 | " | 🔄 | Removed languageNote usage from summary XML template | ~79 |
| #31826 | " | 🔄 | Removed unused languageNote variable from buildSummaryPrompt | ~198 |
| #31825 | 6:26 PM | 🔄 | Removed unused languageNote variable from buildInitPrompt | ~278 |
| #31820 | 6:20 PM | 🔵 | Prompts system architecture uses mode.prompts.format_examples field | ~305 |
| #31816 | 6:10 PM | 🔄 | Extracted memory continuation header to mode configuration | ~236 |
| #31815 | 6:09 PM | 🔄 | Extracted continuation instruction to mode configuration | ~252 |
| #31814 | " | 🔄 | Extracted continuation greeting to mode configuration | ~306 |
| #31813 | 6:08 PM | 🔄 | Removed hardcoded language instruction from buildSummaryPrompt | ~291 |
| #31812 | " | 🔄 | Replaced all XML placeholder text with mode configuration variables | ~459 |
| #31811 | " | 🔄 | Replaced hardcoded memory processing header with mode variable | ~252 |
**parser.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31855 | 6:53 PM | ✅ | テストスイートの大規模削除とテスト分析レポートの追加 | ~197 |
### Dec 23, 2025
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32030 | 7:44 PM | 🔵 | SDK prompt building system uses mode configuration | ~330 |
**parser.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32029 | 7:40 PM | 🔵 | Parser Layer Has No Skip Logic - Always Saves Observations | ~342 |
### Dec 24, 2025
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32213 | 8:17 PM | 🔵 | Prompt Generation System Architecture | ~402 |
| #32337 | 4:03 PM | ✅ | Enhanced observation prompt with granularity reminder | ~278 |
### Dec 25, 2025
**parser.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32701 | 9:00 PM | 🔵 | Test Coverage Report Generated | ~471 |
| #32565 | 8:19 PM | 🔵 | Read parser.ts (first 150 lines) | ~146 |
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32558 | 8:18 PM | 🔵 | Identified files containing 'summary' or 'Summary' | ~167 |
### Dec 27, 2025
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33131 | 7:52 PM | 🔵 | Session ID Propagation Flow Analysis with Architectural Vulnerabilities Identified | ~577 |
| #33129 | " | 🔵 | Prompt Building Functions with Session ID Threading Documentation | ~483 |
### Dec 28, 2025
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33438 | 10:15 PM | 🔄 | Bulk Rename Session ID Fields Across Entire Codebase | ~384 |
| #33420 | 10:06 PM | 🔵 | Complete session ID flow analysis reveals missing SDK session capture mechanism | ~545 |
| #33415 | 10:05 PM | 🔵 | Prompt building functions receive sessionId but only use it for context display | ~372 |
| #33316 | 3:09 PM | 🔴 | Fixed Disconnected SDK Agent Sessions | ~350 |
| #33296 | 3:08 PM | 🔵 | Session ID Propagation Flow Architecture Traced Through Codebase | ~720 |
### Dec 30, 2025
**parser.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34462 | 2:23 PM | 🔵 | Code Quality Review Identifies Critical V2 Migration Issues | ~418 |
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34398 | 1:53 PM | 🔵 | SDK Prompts Module Structure | ~361 |
### Jan 1, 2026
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35666 | 11:37 PM | ✅ | Staged error handling improvements across 10 files | ~261 |
| #35641 | 11:27 PM | ✅ | Added APPROVED OVERRIDE comments for JSON parse error handling in SDK prompts | ~336 |
### Jan 2, 2026
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #35770 | 1:23 PM | ✅ | Last User Message Field Removed Across 11 Files in Codebase | ~374 |
| #35763 | 1:22 PM | 🔄 | Removed last_user_message from SDKSession interface | ~241 |
| #35762 | 1:21 PM | 🔵 | SDKSession interface includes last_user_message field | ~221 |
| #35742 | 1:15 PM | 🔵 | SDKSession interface defines both user_prompt and last_user_message fields | ~289 |
| #35738 | 1:12 PM | 🔵 | Summary prompt uses last_assistant_message but not last_user_message | ~334 |
| #35737 | " | 🔵 | Summary Prompt Interface Defines Optional last_user_message | ~253 |
| #35736 | " | 🔵 | SDKSession Interface Defines Optional last_user_message Field | ~277 |
| #35733 | 1:11 PM | 🔵 | Located last_user_message usage across codebase | ~333 |
### Jan 3, 2026
**parser.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36200 | 7:22 PM | 🔵 | Parser Module Analysis for Phase 2 Refactoring | ~562 |
### Jan 5, 2026
**prompts.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37613 | 5:31 PM | 🔵 | PR #558 Review Feedback Analysis | ~544 |
| #37571 | 4:51 PM | | Phase 1 Anti-Pattern Check Complete - Clean Implementation | ~400 |
| #37557 | 4:49 PM | 🔵 | Issue #545 Bug Location and Fix Pattern Documented | ~462 |
| #37539 | 4:45 PM | 🔵 | SDK Defensive JSON Parsing Pattern Implementation | ~408 |
| #37703 | 6:01 PM | 🔵 | ParsedObservation files_read and files_modified are string arrays parsed from XML | ~330 |
| #37701 | " | 🔵 | Complete cwd data flow traced from hooks through observation processing | ~447 |
### Jan 7, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38454 | 10:26 PM | 🔵 | happyPathError usage pattern in summary prompt generation | ~421 |
| #38405 | 10:07 PM | ⚖️ | DEBUG Log Level Analysis - One Message Requires WARN Promotion | ~819 |
| #38404 | 10:06 PM | ⚖️ | Log Level Audit Analysis - WARN to ERROR Promotion Criteria Established | ~769 |
</claude-mem-context>

View File

@@ -63,10 +63,10 @@ export function parseObservations(text: string, correlationId?: string): ParsedO
if (validTypes.includes(type.trim())) {
finalType = type.trim();
} else {
logger.warn('PARSER', `Invalid observation type: ${type}, using "${fallbackType}"`, { correlationId });
logger.error('PARSER', `Invalid observation type: ${type}, using "${fallbackType}"`, { correlationId });
}
} else {
logger.warn('PARSER', `Observation missing type field, using "${fallbackType}"`, { correlationId });
logger.error('PARSER', `Observation missing type field, using "${fallbackType}"`, { correlationId });
}
// All other fields are optional - save whatever we have
@@ -75,7 +75,7 @@ export function parseObservations(text: string, correlationId?: string): ParsedO
const cleanedConcepts = concepts.filter(c => c !== finalType);
if (cleanedConcepts.length !== concepts.length) {
logger.warn('PARSER', 'Removed observation type from concepts array', {
logger.error('PARSER', 'Removed observation type from concepts array', {
correlationId,
type: finalType,
originalConcepts: concepts,

View File

@@ -123,13 +123,12 @@ export function buildObservationPrompt(obs: Observation): string {
* Build prompt to generate progress summary
*/
export function buildSummaryPrompt(session: SDKSession, mode: ModeConfig): string {
const lastAssistantMessage = session.last_assistant_message || logger.happyPathError(
'SDK',
'Missing last_assistant_message in session for summary prompt',
{ sessionId: session.id },
undefined,
''
);
const lastAssistantMessage = session.last_assistant_message || (() => {
logger.error('SDK', 'Missing last_assistant_message in session for summary prompt', {
sessionId: session.id
});
return '';
})();
return `${mode.prompts.header_summary_checkpoint}
${mode.prompts.summary_instruction}

View File

@@ -3,123 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 21, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31603 | 8:21 PM | 🔵 | Complete Console.* Statement Audit Across Codebase | ~813 |
### Dec 25, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32558 | 8:18 PM | 🔵 | Identified files containing 'summary' or 'Summary' | ~167 |
### Dec 26, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32912 | 10:02 PM | 🔵 | Error handling uses consistent logger.error and logger.failure patterns throughout codebase | ~508 |
### Dec 27, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33175 | 8:34 PM | 🔄 | Console.log interception now uses structured logger | ~288 |
| #33148 | 8:19 PM | 🔵 | Logging System Architecture Traced Across Codebase | ~384 |
### Dec 28, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33653 | 11:48 PM | 🔵 | MCP Server Architecture - Thin Wrapper Over Worker HTTP API | ~433 |
| #33636 | 11:35 PM | ✅ | Major Documentation and Code Cleanup Removed 4,929 Lines | ~381 |
| #33624 | 11:29 PM | 🔄 | Removed callWorkerAPIWithPath function from MCP server | ~275 |
| #33623 | " | 🟣 | Added __IMPORTANT workflow guidance tool to MCP server | ~350 |
| #33622 | " | ✅ | Enhanced get_observations tool description with parameter details | ~274 |
| #33621 | " | ✅ | Enhanced timeline tool to support automatic anchor discovery via query | ~274 |
| #33620 | " | ✅ | Extended search tool parameter documentation in MCP server | ~224 |
| #33619 | " | 🔵 | Confirmed MCP server renamed to mcp-search-server with embedded workflow guidance | ~499 |
| #33618 | 11:28 PM | 🔵 | MCP Server Graceful Shutdown and Worker Verification | ~307 |
| #33611 | 11:22 PM | 🔄 | Removed TOOL_SCHEMAS and cleaned up TOOL_ENDPOINT_MAP | ~358 |
| #33610 | 11:21 PM | 🔵 | TOOL_SCHEMAS retains removed tool definitions | ~318 |
| #33609 | " | ✅ | Cleaned up get_observations parameter description | ~236 |
| #33608 | " | ✅ | Removed get_session and get_prompt tools from MCP server | ~353 |
| #33607 | " | 🔄 | Removed four non-workflow tools from MCP server | ~339 |
| #33606 | " | ✅ | Updated timeline tool description to emphasize workflow step position | ~341 |
| #33605 | " | 🔄 | Removed get_schema tool from MCP server | ~274 |
| #33604 | 11:20 PM | 🔵 | MCP server tool definitions and schema validation pattern | ~477 |
| #33602 | 11:19 PM | 🔵 | MCP Server Architecture - Thin HTTP Wrapper Over Worker API | ~465 |
| #33601 | 11:18 PM | 🔵 | MCP server search tool parameter descriptions examined | ~373 |
| #33600 | 11:15 PM | 🔵 | MCP get_observations tool successfully retrieving full observation details by ID | ~472 |
| #33598 | " | 🔵 | Filtered MCP search query successfully returning rename history with type constraints | ~386 |
| #33597 | 11:14 PM | 🔵 | MCP search tool successfully retrieving mem-search to mcp-search rename history | ~361 |
| #33534 | 10:53 PM | ✅ | Updated internal MCP server name to mcp-search-server | ~351 |
| #33533 | " | 🔵 | Located internal MCP server name at line 438 in mcp-server.ts | ~304 |
| #33531 | 10:52 PM | ⚖️ | Implementation plan approved for MCP server rename and skill workflow enhancement | ~727 |
| #33530 | " | ⚖️ | Rename MCP server from mem-search to mcp-search for clearer namespace separation | ~562 |
| #33511 | 10:44 PM | 🔵 | MCP server implementation provides thin HTTP wrapper over Worker API | ~404 |
| #33328 | 3:10 PM | 🟣 | Merged centralized logger and session continuity diagnostics to main | ~397 |
| #33280 | 3:07 PM | 🔄 | Logger coverage refactor for background services | ~428 |
### Dec 29, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34194 | 9:57 PM | 🔵 | MCP server delegates to Worker HTTP API on localhost:37777 | ~360 |
| #33703 | 12:10 AM | 🔵 | Final Documentation Review Confirms Update Requirements | ~756 |
| #33702 | 12:09 AM | ⚖️ | Documentation Update Strategy Finalized for MCP Architecture Transition | ~845 |
| #33695 | 12:06 AM | 🔵 | Current MCP Server Implementation Validates 4-Tool Architecture | ~556 |
| #33678 | 12:03 AM | 🔄 | Complete Removal of mem-search Skill Documentation | ~453 |
| #33677 | 12:02 AM | 🔄 | MCP Server Tool Consolidation and Workflow Simplification | ~333 |
| #33676 | " | 🔄 | MCP Server Refactored as Thin HTTP Wrapper | ~473 |
| #33675 | " | 🔄 | Major Documentation and Code Cleanup in MCP Clarity Branch | ~491 |
### Dec 30, 2025
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34440 | 2:16 PM | 🔵 | TypeScript type errors identified across multiple components | ~328 |
### Jan 1, 2026
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35619 | 11:07 PM | 🔵 | MCP Server Fatal Error Handling | ~209 |
### Jan 2, 2026
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36020 | 9:13 PM | 🔵 | MCP Server Worker API Error Handling | ~280 |
### Jan 3, 2026
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36296 | 8:04 PM | 🔵 | TypeScript Compilation Check: Pre-Existing Errors Unrelated to Refactoring | ~621 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**mcp-server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38000 | 9:02 PM | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
| #37999 | " | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
| #37562 | 4:50 PM | 🔵 | MCP Server Architecture for Claude Desktop Integration | ~397 |
*No recent activity*
</claude-mem-context>

View File

@@ -299,9 +299,9 @@ async function main() {
setTimeout(async () => {
const workerAvailable = await verifyWorkerConnection();
if (!workerAvailable) {
logger.warn('SYSTEM', 'Worker not available', undefined, { workerUrl: WORKER_BASE_URL });
logger.warn('SYSTEM', 'Tools will fail until Worker is started');
logger.warn('SYSTEM', 'Start Worker with: npm run worker:restart');
logger.error('SYSTEM', 'Worker not available', undefined, { workerUrl: WORKER_BASE_URL });
logger.error('SYSTEM', 'Tools will fail until Worker is started');
logger.error('SYSTEM', 'Start Worker with: npm run worker:restart');
} else {
logger.info('SYSTEM', 'Worker available', undefined, { workerUrl: WORKER_BASE_URL });
}

View File

@@ -3,69 +3,36 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**context-generator.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
**worker-service.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36642 | 10:56 PM | 🔵 | Logger Coverage Test Requirements Analysis | ~483 |
**worker-types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36637 | 10:47 PM | 🟣 | GeminiAgent Analysis Agent Running But Timed Out After 120 Seconds | ~521 |
| #36631 | 10:45 PM | 🔵 | Worker Types Define ActiveSession With Refactored Session ID Properties | ~487 |
### Jan 4, 2026
**worker-types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36758 | 12:34 AM | 🔵 | Issue #531 Root Cause - 73 Lines of Duplicated Export Type Definitions | ~529 |
| #36714 | 12:12 AM | 🔵 | Memory Leak Analysis Report for Issue #532 Generated | ~531 |
| #36712 | 12:11 AM | 🔵 | Memory Leak Analysis for Issue #532 Documented | ~646 |
**worker-service.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36716 | 12:13 AM | 🔵 | Issue #514 Orphaned .jsonl Session Files Analysis | ~616 |
| #36713 | 12:11 AM | 🔵 | Issue #520 Stuck Messages Already Resolved | ~569 |
| #36711 | " | 🔵 | Issue #520 Stuck Messages Analysis - Already Resolved | ~526 |
### Jan 5, 2026
**context-generator.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38079 | 9:55 PM | 🔵 | Context Generator Deprecated - Redirects to Modular Architecture | ~466 |
| #37989 | 8:39 PM | 🔵 | Worker Service CLI Commands | ~370 |
| #37988 | " | 🔵 | Worker Service Hook Command Integration | ~356 |
| #37943 | 8:09 PM | 🔵 | Worker service provides hook command interface | ~372 |
| #37936 | 8:08 PM | 🔵 | Worker service module located in budapest architecture | ~173 |
| #37837 | 6:55 PM | 🔵 | Worker Service CLI Structure and Extension Pattern | ~536 |
| #37836 | 6:54 PM | 🔵 | Worker Service HTTP API Architecture and Hook Integration Pattern | ~639 |
| #37830 | 6:50 PM | ⚖️ | Architectural Refactoring Plan: Unified CLI Hook System | ~631 |
| #37812 | 6:43 PM | 🔵 | WorkerService Architecture and CLI Entry Points | ~447 |
| #37738 | 6:17 PM | 🔵 | ActiveSession and PendingMessage Structures Analyzed for Phase 3 | ~327 |
| #37701 | 6:01 PM | 🔵 | Complete cwd data flow traced from hooks through observation processing | ~447 |
| #37691 | 5:55 PM | 🔵 | ActiveSession interface contains project name but no project root path | ~346 |
| #37418 | 1:04 AM | 🔴 | Fixed CLAUDE.md duplicate content by filtering to direct children only | ~469 |
| #37391 | 12:48 AM | ✅ | Staged 23 CLAUDE.md files with mix of new and modified content | ~400 |
| #37390 | 12:47 AM | ✅ | Regenerated 23 CLAUDE.md files in budapest workspace | ~365 |
### Jan 7, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**worker-service.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38058 | 9:48 PM | 🔵 | Worker Service Architecture - Modular Orchestrator Pattern | ~523 |
| #38005 | 9:03 PM | 🔵 | Comprehensive exploration of PR review items completed | ~438 |
| #38001 | 9:02 PM | 🔵 | worker-service.ts demonstrates proper getWorkerHost() usage pattern | ~243 |
| #38000 | " | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
| #37999 | " | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
| #37649 | 5:50 PM | 🔵 | WorkerService orchestrator imports logger as foundational dependency | ~390 |
| #37546 | 4:47 PM | 🔵 | Worker Service Initialization Sequence Missing Settings File Creation | ~461 |
### Jan 6, 2026
**worker-service.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38446 | 10:26 PM | 🔵 | Worker Service Logs Startup Recovery Failures at WARN Level | ~419 |
| #38444 | 10:25 PM | 🔵 | Worker service auto-recovery error handling pattern | ~393 |
| #38431 | 10:24 PM | 🔵 | ERROR-Level Logging Used Across 21 Source Files | ~480 |
| #38404 | 10:06 PM | ⚖️ | Log Level Audit Analysis - WARN to ERROR Promotion Criteria Established | ~769 |
| #38354 | 9:10 PM | 🔵 | Provider Selection Architecture and Default Settings Location | ~478 |
| #38352 | 9:09 PM | 🔵 | Worker Service Environment Inheritance and Process Spawning Mechanisms | ~469 |
| #38269 | 7:53 PM | 🔵 | Worker Types Shared Type Definitions | ~847 |
| #38256 | 7:49 PM | 🔵 | Worker Service Orchestration Architecture | ~1166 |
</claude-mem-context>

View File

@@ -3,61 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**ObservationCompiler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36562 | 9:49 PM | 🟣 | Phase 4 Context Generation Tests Completed | ~524 |
| #36556 | 9:45 PM | 🟣 | ObservationCompiler Test Suite Created | ~487 |
| #36550 | 9:42 PM | 🔵 | ObservationCompiler Data Retrieval Module | ~463 |
**TokenCalculator.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36561 | 9:49 PM | 🟣 | Phase 4 Context Generation Test Suite Completion | ~606 |
| #36555 | 9:44 PM | 🟣 | TokenCalculator Test Suite Created for Context Module | ~565 |
| #36433 | 9:00 PM | 🔵 | Token Calculation and Context Economics | ~429 |
**ContextBuilder.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36558 | 9:48 PM | 🟣 | ContextBuilder Test Suite with Comprehensive Mocking | ~601 |
| #36434 | 9:00 PM | 🔵 | ContextBuilder Orchestration Pattern | ~445 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
| #36285 | 8:02 PM | 🔄 | Phase 4: ContextBuilder Main Orchestrator Created | ~590 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36557 | 9:47 PM | 🟣 | MarkdownFormatter Test Suite Created | ~520 |
| #36549 | 9:42 PM | 🔵 | Context Generation Module Type System | ~410 |
| #36431 | 9:00 PM | 🔵 | Context Module Type System | ~513 |
| #36292 | 8:04 PM | 🔄 | Phase 4 Module Inventory: 12 Files Created in Context Architecture | ~571 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36552 | 9:43 PM | 🔵 | Context Generation API Documentation for Phase 4 | ~496 |
| #36417 | 8:57 PM | 🔄 | Context Module Public API Design | ~349 |
**ContextConfigLoader.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36551 | 9:42 PM | 🔵 | ContextConfigLoader Mode-Aware Configuration | ~373 |
| #36279 | 8:01 PM | 🔄 | Phase 4: Context Generator Restructure - ContextConfigLoader Extracted | ~476 |
**context**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36304 | 8:06 PM | 🔄 | Git Status: Phase 4 Changes Ready for Commit | ~570 |
| #36297 | 8:05 PM | 🔄 | Phase 4 Type Safety Verification: Zero TypeScript Errors in Context Module | ~591 |
| #36293 | 8:04 PM | 🔄 | Phase 4 Line Count Analysis: 2,081 Lines Across 12 Modular Files | ~628 |
### Jan 5, 2026
**ContextBuilder.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38076 | 9:53 PM | 🟣 | Worktree-Aware Project Filtering for Unified Timeline Context | ~578 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,125 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 21, 2025
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31766 | 11:11 PM | 🟣 | Expansión de ModePrompts con campos de configuración granular | ~327 |
| #31765 | 11:10 PM | 🔵 | Sistema de configuración de modos con interfaces TypeScript | ~321 |
| #31764 | 11:09 PM | ⚖️ | Consulta arquitectónica con Gemini sobre reconstrucción completa de prompts por modos | ~469 |
| #31704 | 9:37 PM | 🔵 | Mode system architecture discovered in claude-mem | ~457 |
| #31428 | 6:56 PM | 🔵 | Domain Types Define Observation System Interfaces | ~292 |
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31747 | 10:43 PM | 🔵 | PR #412 Code Review Identifies Two Critical Bugs in Mode System | ~545 |
| #31746 | 10:42 PM | 🔵 | PR #412 Documentation Audit Identifies Comment Quality Issues | ~535 |
| #31743 | 10:36 PM | 🔵 | PR #412 proposes mode system with inheritance and multilingual support | ~523 |
| #31739 | 10:28 PM | 🟣 | Mode Inheritance System with Parent-Override Pattern | ~373 |
| #31732 | 10:05 PM | 🟣 | Implemented mode inheritance system with parent-override pattern | ~430 |
| #31731 | " | 🟣 | Added deep merge infrastructure for mode inheritance | ~313 |
| #31729 | 9:55 PM | 🟣 | Mode Inheritance Parser Implementation | ~299 |
| #31728 | 9:54 PM | 🔵 | ModeManager System Architecture | ~314 |
| #31727 | " | ⚖️ | Mode Inheritance System for Multilingual Support | ~509 |
| #31725 | 9:51 PM | ⚖️ | Mode Inheritance System Architecture | ~509 |
| #31709 | 9:39 PM | 🔵 | Mode system architecture comprehensively documented | ~588 |
| #31697 | 9:24 PM | 🔵 | Root Cause Found: getPackageRoot() Returns Wrong Directory for ModeManager | ~399 |
| #31662 | 8:56 PM | 🔵 | ModeManager Path Resolution Dependency on getPackageRoot | ~361 |
| #31649 | 8:46 PM | 🟣 | ModeManager singleton implements dynamic mode profile loading | ~363 |
| #31446 | 7:22 PM | 🔵 | ModeManager Loading System Investigation | ~297 |
| #31445 | 7:21 PM | 🔵 | ModeManager Icon Resolution Methods | ~358 |
| #31427 | 6:56 PM | 🔵 | ModeManager Imports ObservationType and ObservationConcept Types | ~192 |
| #31422 | 6:50 PM | 🔵 | Observation Metadata Constants Usage Across Codebase | ~366 |
| #31407 | 6:26 PM | 🔵 | ModeManager provides observation type metadata access methods | ~283 |
### Dec 22, 2025
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31896 | 7:18 PM | ✅ | Commit amendé avec les nouveaux types pour support multilingue des résumés | ~290 |
| #31895 | " | 🟣 | Ajout de quatre champs de prompts de résumé à l'interface ModePrompts | ~347 |
| #31894 | " | 🔵 | Interface ModePrompts contient les placeholders XML pour résumés | ~354 |
| #31808 | 6:07 PM | 🟣 | Added customizable XML placeholder fields to ModePrompts interface | ~432 |
| #31804 | 4:53 PM | ⚖️ | Refined scope for prompt placeholder extraction to mode configuration | ~439 |
| #31803 | 4:52 PM | 🔵 | Explored prompt system architecture for placeholder customization | ~472 |
| #31800 | 4:51 PM | ⚖️ | Initiated design task to extract hardcoded placeholders into mode configuration | ~441 |
| #31797 | 4:49 PM | 🔵 | ModePrompts interface defines high-level prompt sections but not field placeholders | ~364 |
| #31793 | 4:41 PM | 🔵 | Completed comprehensive exploration of mode system architecture | ~525 |
| #31784 | 4:37 PM | 🔵 | Examined ModeConfig type definitions for prompt customization | ~317 |
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31790 | 4:39 PM | 🔵 | Identified files that interact with ModeManager and prompts | ~332 |
| #31785 | 4:37 PM | 🔵 | Examined ModeManager for mode loading and inheritance system | ~286 |
### Dec 23, 2025
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32033 | 7:50 PM | ⚖️ | Mode-to-Settings Auto-Sync Architecture Designed | ~583 |
| #32032 | 7:45 PM | 🔵 | Queue System Bug: Mode Loaded Once at Startup Prevents Processing | ~450 |
| #32026 | 7:39 PM | 🔵 | Email Investigation Mode Configuration Located | ~300 |
| #32025 | 7:35 PM | 🔵 | ModeManager Implementation with Inheritance System | ~474 |
### Dec 24, 2025
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32214 | 8:17 PM | 🔵 | ModeManager singleton handles mode profiles with inheritance support | ~483 |
### Dec 25, 2025
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32701 | 9:00 PM | 🔵 | Test Coverage Report Generated | ~471 |
| #32580 | 8:22 PM | 🔵 | Grep for resetStuckMessages and processing | ~242 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32558 | 8:18 PM | 🔵 | Identified files containing 'summary' or 'Summary' | ~167 |
### Dec 31, 2025
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34631 | 3:02 PM | 🟣 | Context-Preservation Workflow Design Documents Created | ~729 |
| #34610 | 2:58 PM | 🔵 | Mode Configuration System Architecture for Memory Agent Behavior | ~570 |
### Jan 1, 2026
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35433 | 8:43 PM | 🔵 | Try-Catch Block Distribution Across Services | ~372 |
### Jan 2, 2026
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
### Jan 3, 2026
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36539 | 9:39 PM | 🔵 | ModeManager Singleton Pattern with Inheritance | ~343 |
### Jan 5, 2026
**ModeManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,75 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36571 | 9:54 PM | 🟣 | Phase 5 Infrastructure Tests Completed | ~504 |
| #36570 | " | 🟣 | ProcessManager Infrastructure Test Suite Created | ~535 |
**GracefulShutdown.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36569 | 9:54 PM | 🟣 | GracefulShutdown Test Suite Created | ~457 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**HealthMonitor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36568 | 9:53 PM | 🟣 | HealthMonitor Test Suite Created for Phase 5 | ~437 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36566 | 9:51 PM | 🔵 | Phase 5 Infrastructure APIs Documented | ~506 |
### Jan 4, 2026
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | ✅ | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36914 | 2:24 AM | 🔵 | Recent commit 4d0a10c fixed multiple GitHub issues | ~365 |
| #36846 | 1:45 AM | 🔵 | WMIC Process Management Implementation for Windows | ~569 |
| #36829 | 1:40 AM | 🔵 | PR #542 Review Analysis - Multi-Issue Fix Validation | ~562 |
| #36827 | 1:03 AM | ✅ | Branch diff shows 1,293 insertions and 98 deletions across 15 files | ~464 |
| #36823 | 1:00 AM | 🔴 | GitHub Issue #517 Anti-Pattern Verification Complete - All Checks Passed | ~517 |
| #36822 | 12:59 AM | 🔴 | Final Verification: No PowerShell $_ Variables Remain - Only Explanatory Comment | ~432 |
| #36821 | " | 🟣 | Verified All Timeout Values Preserved at 60000ms | ~467 |
| #36820 | " | 🟣 | Verified taskkill Command Unchanged Across ProcessManager | ~471 |
| #36819 | " | 🟣 | Verified Unix/macOS Process Enumeration Unchanged | ~408 |
| #36818 | 12:58 AM | 🟣 | Verified PID Validation Logic Preserved Across ProcessManager | ~140 |
| #36817 | " | 🔴 | GitHub Issue #517 Implementation Complete and Verified | ~510 |
| #36815 | " | 🔴 | Verified Complete Removal of PowerShell $_ Variables | ~420 |
| #36814 | 12:57 AM | 🟣 | Verified Complete WMIC Migration in ProcessManager | ~454 |
| #36813 | " | 🟣 | Verified Consistent WMIC Output Parsing Pattern | ~392 |
| #36812 | " | 🔴 | GitHub Issue #517 Complete - Replaced PowerShell with WMIC in Both Functions | ~543 |
| #36811 | " | 🔴 | Replaced PowerShell with WMIC in getChildProcesses Function | ~480 |
| #36810 | " | 🔵 | ProcessManager PowerShell Commands Use $_ Variable Pattern | ~486 |
| #36779 | 12:44 AM | 🔵 | ProcessManager Windows PowerShell Functions Complete Analysis | ~550 |
| #36771 | 12:42 AM | 🔵 | ProcessManager Uses execAsync and taskkill Commands | ~390 |
| #36761 | 12:36 AM | ✅ | Created Implementation Plans for Four GitHub Issues | ~507 |
| #36720 | 12:15 AM | 🔵 | Issue #517 Windows PowerShell Analysis Completed | ~631 |
| #36718 | " | 🔵 | Issue #517 Analysis - Windows PowerShell Variable Escaping Bug | ~482 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**HealthMonitor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38005 | 9:03 PM | 🔵 | Comprehensive exploration of PR review items completed | ~438 |
| #38002 | " | 🔵 | HealthMonitor.ts uses hard-coded 127.0.0.1 for health checks | ~338 |
| #38000 | 9:02 PM | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37558 | 4:49 PM | 🔵 | Issue #555 Windows Hook Execution Patterns and Fix Strategy Documented | ~510 |
*No recent activity*
</claude-mem-context>

View File

@@ -86,7 +86,7 @@ export async function httpShutdown(port: number): Promise<boolean> {
return false;
}
// Unexpected error - log full details
logger.warn('SYSTEM', 'Shutdown request failed unexpectedly', { port }, error as Error);
logger.error('SYSTEM', 'Shutdown request failed unexpectedly', { port }, error as Error);
return false;
}
}

View File

@@ -100,7 +100,7 @@ export async function getChildProcesses(parentPid: number): Promise<number[]> {
.filter(n => !isNaN(n) && Number.isInteger(n) && n > 0);
} catch (error) {
// Shutdown cleanup - failure is non-critical, continue without child process cleanup
logger.warn('SYSTEM', 'Failed to enumerate child processes', { parentPid }, error as Error);
logger.error('SYSTEM', 'Failed to enumerate child processes', { parentPid }, error as Error);
return [];
}
}
@@ -213,7 +213,7 @@ export async function cleanupOrphanedProcesses(): Promise<void> {
}
} catch (error) {
// Orphan cleanup is non-critical - log and continue
logger.warn('SYSTEM', 'Failed to enumerate orphaned processes', {}, error as Error);
logger.error('SYSTEM', 'Failed to enumerate orphaned processes', {}, error as Error);
return;
}

View File

@@ -3,25 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**CursorHooksInstaller.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**CursorHooksInstaller.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38075 | 9:53 PM | 🟣 | Initial Folder CLAUDE.md Timeline Formatting Implementation | ~463 |
| #38063 | 9:50 PM | 🔵 | Cursor Integration Module - Context File Updates and Project Registry | ~613 |
| #38000 | 9:02 PM | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
| #37999 | " | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
*No recent activity*
</claude-mem-context>

View File

@@ -117,7 +117,7 @@ export async function updateCursorContextForProject(projectName: string, port: n
logger.debug('CURSOR', 'Updated context file', { projectName, workspacePath: entry.workspacePath });
} catch (error) {
// [ANTI-PATTERN IGNORED]: Background context update - failure is non-critical, user workflow continues
logger.warn('CURSOR', 'Failed to update context file', { projectName }, error as Error);
logger.error('CURSOR', 'Failed to update context file', { projectName }, error as Error);
}
}
@@ -234,7 +234,7 @@ export function configureCursorMcp(target: CursorInstallTarget): number {
}
} catch (error) {
// [ANTI-PATTERN IGNORED]: Fallback behavior - corrupt config, continue with empty
logger.warn('SYSTEM', 'Corrupt mcp.json, creating new config', { path: mcpJsonPath }, error as Error);
logger.error('SYSTEM', 'Corrupt mcp.json, creating new config', { path: mcpJsonPath }, error as Error);
config = { mcpServers: {} };
}
}

View File

@@ -3,56 +3,95 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 10, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23833 | 11:15 PM | 🔵 | ProcessManager Class Already Implemented | ~525 |
| #23823 | 11:12 PM | 🔵 | ProcessManager Accepts Port Parameter in start() Method | ~305 |
| #23815 | 10:52 PM | 🟣 | BinaryManager for Windows Exe Distribution Implemented | ~384 |
| #23814 | " | 🟣 | ProcessManager Core Implementation Created | ~482 |
### Dec 11, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23851 | 12:10 AM | 🔵 | ProcessManager Architecture Details Revealed | ~423 |
### Dec 12, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24359 | 7:00 PM | 🟣 | Phase 1 Critical Code Fixes Completed via Agent Task | ~441 |
| #24358 | 6:59 PM | ✅ | Completed Phase 1 Code Fixes for better-sqlite3 Migration | ~385 |
| #24350 | 6:58 PM | 🟣 | Added Port Validation to ProcessManager.start() | ~348 |
| #24346 | 6:57 PM | 🔵 | ProcessManager.start() Lacks Port Validation | ~327 |
### Dec 14, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #26766 | 11:30 PM | ⚖️ | Root Cause Identified: Missing Post-Install Worker Restart Trigger in Plugin Update Flow | ~604 |
| #26765 | " | 🔵 | Explore Agent Confirms Root Cause: No Proactive Worker Restart After Plugin Updates | ~613 |
| #26736 | 11:25 PM | 🔵 | ProcessManager Restart Has No Delay Between Stop and Start | ~437 |
| #26735 | " | 🔵 | ProcessManager.restart Calls Stop Then Start With No Additional Delay | ~454 |
### Dec 16, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27787 | 6:29 PM | 🔵 | ProcessManager Uses PowerShell Start-Process with Hidden Windows | ~355 |
| #27408 | 3:24 PM | 🔵 | ProcessManager Security Analysis for Command Injection Vulnerability | ~428 |
### Dec 17, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28476 | 4:26 PM | 🔵 | ProcessManager Windows Wrapper Pattern for Zombie Port Prevention | ~620 |
| #28932 | 7:30 PM | 🔵 | ProcessManager Architecture and Platform-Specific Process Spawning | ~523 |
| #28929 | " | 🔵 | ProcessManager Usage Across Codebase | ~319 |
| #28747 | 6:25 PM | 🔵 | Branch Diff Analysis - 26 Files Modified | ~374 |
| #28730 | 6:21 PM | 🔵 | Worker Wrapper Solves Windows Zombie Port Problem | ~416 |
| #28729 | " | 🔵 | Windows Worker Wrapper Architecture | ~222 |
| #28721 | 6:18 PM | 🔵 | Final Solution - Worker Wrapper Architecture Successfully Deployed | ~474 |
| #28719 | " | 🔵 | Initial Windows Worker Problem Analysis - Three Interconnected Issues | ~564 |
| #28714 | 6:15 PM | 🔴 | Windows Zombie Port Problem Resolved with Wrapper Process Architecture | ~421 |
| #28711 | 6:13 PM | 🔵 | Overview of Changes Between main and HEAD Branch | ~347 |
| #28660 | 5:31 PM | 🔵 | Branch Modifies 26 Files with Net Addition of 346 Lines | ~445 |
| #28644 | 5:24 PM | ✅ | Modified 27 files with 693 additions and 239 deletions for Windows support | ~447 |
### Dec 18, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29622 | 5:41 PM | 🔵 | Validation Patterns Across HTTP Routes and Core Services | ~488 |
### Dec 20, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30947 | 7:01 PM | 🔵 | Timeout Constants Usage Patterns Verified | ~416 |
| #30946 | " | 🔵 | ProcessManager Timeout Constants Located | ~348 |
| #31066 | 7:53 PM | 🔵 | Comprehensive KISS Principle Audit of Hooks and Worker Services | ~788 |
| #31020 | 7:28 PM | 🔄 | Inlined single-use timeout constants in ProcessManager | ~390 |
| #31013 | 7:27 PM | 🔵 | Comment Analysis Identified Stale FTS5 References and Documentation Gaps | ~681 |
| #31012 | 7:25 PM | 🔴 | Silent Failure Review Identified Regression in getWorkerPort() Error Handling | ~659 |
| #31010 | " | ⚖️ | PR #400 Approved After Comprehensive Code Review | ~594 |
| #31000 | 7:22 PM | 🔄 | ProcessManager timeout constants inlined to literal values | ~356 |
| #30993 | 7:20 PM | 🔴 | ProcessManager getPidInfo() enhanced with error logging | ~290 |
| #30990 | 7:19 PM | 🔵 | PR 400 achieves net deletion of 395 lines across 31 files | ~338 |
| #30988 | " | 🔵 | PR 400 modifies 31 files across hooks, services, and utilities | ~316 |
| #30986 | " | 🔵 | PR #400 File Scope: 31 Files Across Hooks, Services, and Utilities | ~526 |
| #30953 | 7:02 PM | 🔄 | Removed Single-Use Timeout Constants in ProcessManager | ~306 |
| #30949 | " | 🔴 | Fixed undefined constant in ProcessManager waitForExit | ~245 |
| #30948 | 7:01 PM | 🔵 | Windows Process Shutdown Strategy in ProcessManager | ~302 |
| #30907 | 6:46 PM | 🔴 | ProcessManager PID File Corruption Now Logs Warnings | ~326 |
| #30905 | 6:45 PM | 🔴 | ProcessManager getPidInfo Error Visibility | ~333 |
| #30902 | " | 🔴 | Added logging to PID file error handling in ProcessManager | ~260 |
| #30901 | 6:44 PM | 🔵 | Windows Graceful Shutdown via HTTP and Wrapper IPC | ~269 |
| #30900 | " | 🔵 | Platform-Specific Worker Script Selection | ~262 |
| #30899 | " | 🔵 | getPidInfo Usage Pattern in ProcessManager | ~206 |
| #30898 | " | 🔵 | ProcessManager PID File Management Implementation | ~249 |
| #30774 | 5:58 PM | 🔵 | ProcessManager Handles Cross-Platform Worker Lifecycle with Windows Workarounds | ~559 |
| #32307 | 5:56 PM | 🔵 | Worker Service Code Audit: 14 Issues Found Across Validation, Data Structures, and Complexity | ~793 |
| #30673 | 5:08 PM | 🔴 | Windows Worker Stop/Restart Reliability Improvements | ~376 |
| #30663 | 5:07 PM | 🔵 | Cross-Platform Support Across 12 Files | ~307 |
### Dec 24, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32071 | 3:24 PM | ⚖️ | Worker Startup Architecture Redesigned | ~380 |
| #32070 | " | 🔵 | ProcessManager Worker Spawning Architecture | ~428 |
| #32059 | 3:17 PM | ⚖️ | Worker Startup Refactored with File-Based Locking for Concurrent Hooks | ~552 |
### Dec 26, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32855 | 7:04 PM | 🔄 | Consolidated worker process management into single service | ~322 |
| #32837 | 6:25 PM | 🔵 | Deleted ProcessManager.ts contained comprehensive PID file infrastructure | ~430 |
| #32814 | 6:05 PM | ✅ | Increased All Timeout Limits to Maximum Values for Slow Systems | ~385 |
### Dec 28, 2025
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33370 | 3:47 PM | 🔵 | ToxMox Wrapper Architecture Deleted December 26, Six Days After Implementation | ~506 |
| #33369 | 3:46 PM | 🔵 | ToxMox December 17 Commit Introduced Wrapper Architecture to Fix Windows Zombie Port Bug | ~632 |
| #33368 | 3:45 PM | 🔵 | ToxMox December 20 Commit Improved Windows Worker Restart Reliability and Logging | ~487 |
| #33294 | 3:08 PM | ✅ | ToxMox Contributions Documented in Comprehensive Markdown Report | ~603 |
| #33284 | 3:07 PM | 🔄 | Consolidated Worker Lifecycle Management (-580 Lines) | ~327 |
| #33270 | 2:59 PM | ⚖️ | Self-Spawn Pattern Chosen for Worker Lifecycle | ~418 |
### Jan 6, 2026
**ProcessManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
| #38105 | 12:14 AM | 🔵 | Windows Console Popup Flash Issue Documented and Fixed | ~455 |
</claude-mem-context>

View File

@@ -3,58 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 28, 2025
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33396 | 9:53 PM | ✅ | Queue refactoring touched 12 files with net addition of 1021 lines | ~402 |
| #33395 | " | 🟣 | Queue system refactored with atomic message processing | ~487 |
| #33374 | 7:12 PM | 🟣 | Refactored Queue System with Atomic Message Claiming and In-Memory State Elimination | ~477 |
| #33384 | " | 🔵 | Confirmed `SessionQueueProcessor` Integration in `SessionManager` | ~289 |
| #33387 | " | ⚖️ | Formulated Plan to Address PR #470 Review Issues | ~441 |
### Dec 30, 2025
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34409 | 1:55 PM | 🔵 | SessionQueueProcessor Event-Driven Message Iteration | ~433 |
| #34391 | 1:40 PM | 🔵 | SessionQueueProcessor Respects Abort Signal But Only Stops Iterator Loop | ~382 |
### Jan 1, 2026
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35521 | 9:35 PM | 🔵 | Queue Processor Uses Database-Backed Message Store | ~316 |
| #35433 | 8:43 PM | 🔵 | Try-Catch Block Distribution Across Services | ~372 |
| #35432 | " | 🔵 | Services Directory Structure Mapped | ~268 |
### Jan 2, 2026
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
| #35887 | 2:47 PM | 🔵 | SessionQueueProcessor Has Error Recovery But Doesn't Mark Failed | ~353 |
| #35851 | 2:32 PM | 🔵 | Queue Processor Uses Atomic Claiming with Event-Driven Wake-Up | ~464 |
### Jan 3, 2026
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36343 | 8:29 PM | 🔄 | SessionQueueProcessor Updated to Use claimAndDelete | ~299 |
| #36340 | 8:28 PM | 🔵 | Complete Duplicate Bug Analysis via Explore Agent | ~435 |
| #36323 | 8:25 PM | 🔵 | Message Queue Architecture Scope Expanded | ~302 |
| #36314 | " | 🔵 | Message Queue Processing Duplicate Bug Investigation | ~316 |
### Jan 4, 2026
**SessionQueueProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36713 | 12:11 AM | 🔵 | Issue #520 Stuck Messages Already Resolved | ~569 |
| #36711 | " | 🔵 | Issue #520 Stuck Messages Analysis - Already Resolved | ~526 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,32 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**Server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36689 | 11:56 PM | 🔵 | PR #538 Review Findings - Modular Architecture Refactor | ~590 |
| #36583 | 9:57 PM | 🟣 | Server Test Suite Created | ~485 |
| #36427 | 8:59 PM | 🔵 | Server Class Architecture and Route Registration | ~447 |
**ErrorHandler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36581 | 9:57 PM | 🟣 | ErrorHandler Test Suite Created for Phase 6 | ~444 |
| #36454 | 9:03 PM | 🔵 | Centralized Express Error Handling | ~446 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36575 | 9:55 PM | 🔵 | Server Layer API Documentation for Phase 6 | ~521 |
### Jan 5, 2026
**Server.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37758 | 6:25 PM | ⚖️ | Integration Test Design for Four Critical Testing Gaps | ~729 |
| #37533 | 4:44 PM | 🔵 | Windows IPC Detection Logic and Managed Mode Handling | ~427 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,125 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
**SessionStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36101 | 10:25 PM | ✅ | Database migration made observations.text field nullable | ~353 |
| #36100 | " | 🔵 | storeObservation method implementation in SessionStore | ~368 |
| #36085 | 10:15 PM | 🔵 | Memory Session ID Two-Phase Capture Pattern | ~350 |
| #36084 | " | 🔵 | SDK Session Creation Idempotent Design Pattern | ~410 |
| #36029 | 9:21 PM | 🔄 | Removed try-catch block from ensureDiscoveryTokensColumn migration | ~322 |
| #35998 | 5:32 PM | 🔴 | Critical Session ID Placeholder Bug Fixed to Prevent Transcript Pollution | ~488 |
| #35995 | 5:31 PM | 🔵 | Worker Version Mismatch Detection Issue | ~419 |
| #35990 | 5:17 PM | 🔴 | Fixed memory_session_id initialization to prevent session ID collision | ~385 |
| #35989 | " | 🔵 | SDK Session Creation Uses Content Session ID as Memory Session Placeholder | ~399 |
| #35988 | " | 🔵 | Session ID Threading Architecture with FK Placeholder Pattern | ~380 |
| #35970 | 4:47 PM | 🔵 | Session ID Logging Distribution Across Codebase | ~485 |
| #35959 | 4:44 PM | 🔵 | SessionStore Database Schema and Session ID Architecture | ~684 |
**migrations.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
**PendingMessageStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #35885 | 2:46 PM | 🔵 | PendingMessageStore Implements Four-State Lifecycle | ~411 |
| #35858 | 2:33 PM | 🔵 | PendingMessageStore Provides Stuck Message Recovery Methods | ~496 |
| #35855 | " | 🔵 | PendingMessageStore Implements Database-Backed Message Queue with Status Tracking | ~518 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35840 | 2:30 PM | 🔵 | Database Schema Includes Observation Status Tracking | ~488 |
### Jan 3, 2026
**transactions.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36689 | 11:56 PM | 🔵 | PR #538 Review Findings - Modular Architecture Refactor | ~590 |
| #36486 | 9:12 PM | 🟣 | Transactions Module Test Suite Implemented | ~833 |
| #36350 | 8:30 PM | 🔄 | Renamed StoreAndMarkCompleteResult to StoreObservationsResult | ~278 |
| #36348 | " | 🔵 | Transaction Module Structure for Observation Storage | ~370 |
| #36323 | 8:25 PM | 🔵 | Message Queue Architecture Scope Expanded | ~302 |
**Import.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
**SessionStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36636 | 10:46 PM | 🟣 | Session ID Refactor Analysis Agent Completed Comprehensive Report | ~637 |
| #36635 | " | 🟣 | SessionStore Analysis Agent Completed Report Generation | ~545 |
| #36621 | 10:43 PM | 🔵 | SessionStore Implementation Already Supports Timestamp Override | ~491 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
| #36355 | 8:42 PM | 🔵 | SessionStore observations table uses 5-type enum constraint | ~273 |
| #36353 | " | 🔵 | Multiple observation table definitions found across codebase | ~280 |
| #36339 | 8:28 PM | 🔵 | Message Completion SQL Update in Transaction | ~343 |
| #36332 | 8:27 PM | 🔵 | Transaction Structure in storeObservationsAndMarkComplete | ~353 |
| #36117 | 6:19 PM | 🔵 | SessionStore Architecture: 2,012 Lines Managing 20 Migrations and 49 Methods | ~578 |
| #36113 | 3:58 PM | 🔴 | Fixed FOREIGN KEY Constraint Failure in Observation Storage | ~448 |
**Sessions.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36470 | 9:06 PM | 🔵 | SQLite Module API Documentation Verified for Test Implementation | ~765 |
**Database.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36435 | 9:00 PM | 🔵 | SQLite Database Configuration and Migration Management | ~476 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36416 | 8:57 PM | 🔄 | SQLite Module Public API with SessionStore Deprecation | ~402 |
| #36351 | 8:31 PM | 🔵 | SQLite Module Index Exports storeObservationsAndMarkComplete | ~268 |
| #36314 | 8:25 PM | 🔵 | Message Queue Processing Duplicate Bug Investigation | ~316 |
**PendingMessageStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36342 | 8:29 PM | 🔄 | Implemented claimAndDelete Method in PendingMessageStore | ~353 |
| #36340 | 8:28 PM | 🔵 | Complete Duplicate Bug Analysis via Explore Agent | ~435 |
| #36329 | 8:25 PM | 🔵 | PendingMessageStore State Machine Architecture | ~393 |
| #36127 | 6:20 PM | 🔵 | PendingMessageStore Implements Persistent Work Queue for Crash Recovery | ~539 |
**sqlite**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36296 | 8:04 PM | 🔵 | TypeScript Compilation Check: Pre-Existing Errors Unrelated to Refactoring | ~621 |
**migrations.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36124 | 6:19 PM | 🔵 | Migrations File Contains 7 Separate Migration Definitions | ~509 |
### Jan 4, 2026
**SessionStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36780 | 12:44 AM | 🔵 | Observation Schema Evolution with Hierarchical Fields | ~452 |
| #36770 | 12:42 AM | 🔵 | Export Script Type Duplication Analysis Complete | ~555 |
**PendingMessageStore.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36713 | 12:11 AM | 🔵 | Issue #520 Stuck Messages Already Resolved | ~569 |
| #36711 | " | 🔵 | Issue #520 Stuck Messages Analysis - Already Resolved | ~526 |
### Jan 5, 2026
**SessionSearch.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38036 | 9:43 PM | 🟣 | Configurable Observation Limits and Enhanced Folder Search | ~418 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,30 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**create.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
| #36482 | 9:10 PM | 🟣 | Sessions Module Test Suite Implemented | ~627 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36470 | 9:06 PM | 🔵 | SQLite Module API Documentation Verified for Test Implementation | ~765 |
| #36439 | 9:01 PM | 🔵 | Session Type Hierarchy | ~420 |
**get.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36438 | 9:01 PM | 🔵 | Session Retrieval Functions with Database-First Pattern | ~479 |
### Jan 4, 2026
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36770 | 12:42 AM | 🔵 | Export Script Type Duplication Analysis Complete | ~555 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,10 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**queries.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,137 +3,17 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 21, 2025
### Jan 7, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31745 | 10:42 PM | 🔵 | PR #412 Error Handling Audit Reveals Seven Silent Failure Patterns | ~529 |
| #31741 | 10:29 PM | 🟣 | Configurable Local Embedding Models with Multilingual Support | ~461 |
| #31738 | 10:26 PM | 🔵 | Configurable Embedding Models Already Implemented in Feature Branch | ~622 |
| #31737 | 10:23 PM | 🔵 | ChromaSync Embedding Architecture Investigation | ~582 |
### Dec 22, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31790 | 4:39 PM | 🔵 | Identified files that interact with ModeManager and prompts | ~332 |
### Dec 24, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32154 | 6:41 PM | 🔵 | ChromaSync Vector Database Architecture | ~558 |
| #32153 | 6:40 PM | 🔵 | Session Identifier Architecture Across Codebase | ~529 |
### Dec 25, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32558 | 8:18 PM | 🔵 | Identified files containing 'summary' or 'Summary' | ~167 |
### Dec 26, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32912 | 10:02 PM | 🔵 | Error handling uses consistent logger.error and logger.failure patterns throughout codebase | ~508 |
### Dec 27, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33245 | 9:53 PM | 🔵 | Chroma Collection Creation Fails Silently in Fire-and-Forget Backfill | ~355 |
| #33244 | " | 🔵 | Commit 63fd158 Removed Double JSON Serialization from SDKAgent | ~304 |
| #33242 | 9:52 PM | 🔵 | ChromaSync Double-JSON Pattern Intact - Regression Not From Code Changes | ~367 |
| #33241 | " | 🔵 | mem-search Regression Root Cause: Silent ChromaSync Initialization Failures | ~568 |
| #33240 | 9:51 PM | 🔵 | mem-search Regression Root Cause: Silent ChromaSync Initialization Failures | ~478 |
| #33239 | 9:50 PM | 🔵 | mem-search Regression Root Cause: Silent ChromaSync Initialization Failures | ~460 |
| #33238 | 9:49 PM | 🔵 | Chroma Vector Search Initialization Failure in DatabaseManager | ~446 |
| #33233 | 9:44 PM | 🔵 | Vector Search Unavailable in mem-search - Chroma Not Initialized | ~335 |
| #33225 | 9:37 PM | 🔵 | Worker Performance Barriers Analysis | ~415 |
| #33224 | 9:35 PM | 🔵 | Worker Performance Barriers: Timeouts and Rate Limiting | ~491 |
| #33082 | 6:45 PM | 🔵 | User directory path patterns in codebase | ~362 |
### Dec 28, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33439 | 10:15 PM | 🔄 | Extended Session ID Renaming to Additional Codebase Components | ~352 |
| #33322 | 3:09 PM | 🔵 | Worker Performance Bottlenecks Identified Across Multiple Subsystems | ~399 |
| #33299 | 3:08 PM | 🔵 | mem-search Regression Caused by Logger Error Serialization Bug | ~417 |
| #33292 | " | 🔄 | ChromaSync Lazy Initialization Replaces Startup Backfill | ~398 |
### Dec 29, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33860 | 4:35 PM | 🔵 | Comprehensive Bun integration architecture and platform-specific implementation details | ~619 |
| #33791 | 3:48 PM | 🔵 | ChromaSync.close() terminates subprocess via transport.close() | ~302 |
| #33786 | 3:47 PM | 🔵 | ChromaDB vector database synchronization architecture | ~535 |
| #33778 | 3:36 PM | 🔵 | ChromaSync spawns chroma-mcp subprocess via StdioClientTransport | ~419 |
### Dec 30, 2025
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34440 | 2:16 PM | 🔵 | TypeScript type errors identified across multiple components | ~328 |
### Jan 1, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35434 | 8:45 PM | 🔵 | Comprehensive Try-Catch Audit of Worker Service Error Handling | ~792 |
| #35433 | 8:43 PM | 🔵 | Try-Catch Block Distribution Across Services | ~372 |
| #35432 | " | 🔵 | Services Directory Structure Mapped | ~268 |
### Jan 2, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
| #35902 | 2:49 PM | 🔴 | Improved ChromaSync Error Logging | ~280 |
| #35901 | " | 🔵 | PR #525 File Changes Summary | ~376 |
| #35864 | 2:35 PM | 🔵 | Chroma Sync Methods Block on addDocuments Completion | ~441 |
| #35861 | 2:34 PM | 🔵 | ChromaSync Provides Vector Database Integration with Fail-Fast Design | ~476 |
| #35789 | 1:53 PM | ⚖️ | Error Logging Anti-Pattern Identified: Incomplete Error Information | ~404 |
| #35785 | 1:46 PM | 🔵 | Incomplete Error Logging Pattern in ChromaSync Collection Check | ~349 |
| #35783 | 1:45 PM | ⚖️ | Error Logging Anti-Pattern Identification Task | ~399 |
| #35775 | 1:24 PM | 🔵 | ensureConnection Call Sites in ChromaSync | ~309 |
| #35774 | " | 🔴 | Added Connection Error Detection in ensureCollection | ~342 |
| #35773 | " | 🔵 | ChromaSync Service Architecture and Connection Flow | ~420 |
| #35726 | 1:09 PM | ✅ | ChromaDB Error Handling Fix Committed to Bugfix Branch | ~314 |
| #35725 | " | 🔴 | ChromaDB Connection Error Handling Fixed | ~335 |
| #35724 | " | ✅ | Bugfix Branch Created with ChromaDB Connection Changes | ~303 |
### Jan 3, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36296 | 8:04 PM | 🔵 | TypeScript Compilation Check: Pre-Existing Errors Unrelated to Refactoring | ~621 |
### Jan 5, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37758 | 6:25 PM | ⚖️ | Integration Test Design for Four Critical Testing Gaps | ~729 |
### Jan 6, 2026
**ChromaSync.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
| #38105 | 12:14 AM | 🔵 | Windows Console Popup Flash Issue Documented and Fixed | ~455 |
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38449 | 10:26 PM | 🔵 | ChromaSync Error Handling: Throw After ERROR Log Pattern | ~452 |
| #38437 | 10:24 PM | 🔵 | Claude-mem core functionality and logging patterns identified | ~710 |
| #38432 | " | 🔵 | ChromaSync class architecture and fail-fast design pattern | ~508 |
| #38431 | " | 🔵 | ERROR-Level Logging Used Across 21 Source Files | ~480 |
| #38425 | " | ⚖️ | Log Level Architecture: Fail-Critical Over Fail-Fast for Chroma | ~467 |
| #38418 | 10:22 PM | 🔵 | ChromaDB Operates as Optional Subsystem with Graceful Degradation | ~586 |
| #38416 | " | 🔵 | ChromaDB Is Critical Not Optional - Log Audit Findings Challenged | ~405 |
| #38202 | 7:38 PM | 🔵 | ChromaSync Service Architecture | ~516 |
</claude-mem-context>

View File

@@ -182,7 +182,7 @@ export class ChromaSync {
}
// Only attempt creation if it's genuinely a "collection not found" error
logger.warn('CHROMA_SYNC', 'Collection check failed, attempting to create', { collection: this.collectionName }, error as Error);
logger.error('CHROMA_SYNC', 'Collection check failed, attempting to create', { collection: this.collectionName }, error as Error);
logger.info('CHROMA_SYNC', 'Creating collection', { collection: this.collectionName });
try {
@@ -826,13 +826,13 @@ export class ChromaSync {
throw error;
}
const resultText = logger.happyPathError(
'CHROMA',
'Missing text in MCP chroma_query_documents result',
{ project: this.project },
{ query_text: query },
result.content[0]?.text || ''
);
const resultText = result.content[0]?.text || (() => {
logger.error('CHROMA', 'Missing text in MCP chroma_query_documents result', {
project: this.project,
query_text: query
});
return '';
})();
// Parse JSON response
let parsed: any;

View File

@@ -287,7 +287,7 @@ export class WorkerService {
});
}
}).catch(error => {
logger.warn('SYSTEM', 'Auto-recovery of pending queues failed', {}, error as Error);
logger.error('SYSTEM', 'Auto-recovery of pending queues failed', {}, error as Error);
});
} catch (error) {
logger.error('SYSTEM', 'Background initialization failed', {}, error as Error);
@@ -366,7 +366,7 @@ export class WorkerService {
await new Promise(resolve => setTimeout(resolve, 100));
} catch (error) {
logger.warn('SYSTEM', `Failed to process session ${sessionDbId}`, {}, error as Error);
logger.error('SYSTEM', `Failed to process session ${sessionDbId}`, {}, error as Error);
result.sessionsSkipped++;
}
}

View File

@@ -242,7 +242,7 @@ export async function switchBranch(targetBranch: string): Promise<SwitchResult>
}
} catch (recoveryError) {
// [POSSIBLY RELEVANT]: Recovery checkout failed, user needs manual intervention - already logging main error above
logger.warn('BRANCH', 'Recovery checkout also failed', { originalBranch: info.branch }, recoveryError as Error);
logger.error('BRANCH', 'Recovery checkout also failed', { originalBranch: info.branch }, recoveryError as Error);
}
return {

View File

@@ -3,125 +3,47 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**Search.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
**GeminiAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36637 | 10:47 PM | 🟣 | GeminiAgent Analysis Agent Running But Timed Out After 120 Seconds | ~521 |
| #36620 | 10:43 PM | 🔵 | GeminiAgent Implementation Uses Refactored Session ID Properties | ~508 |
| #36213 | 7:28 PM | 🔄 | Refactored GeminiAgent to Use Shared Utilities | ~596 |
**SDKAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36625 | 10:44 PM | 🔵 | Documentation and Code Reveal Placeholder Detection Pattern | ~583 |
| #36331 | 8:26 PM | 🔵 | SDKAgent Message Processing Flow | ~366 |
| #36212 | 7:27 PM | 🔄 | Refactored SDKAgent to Use Shared ResponseProcessor | ~616 |
**TimelineService.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36523 | 9:34 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Services | ~386 |
| #36519 | " | 🔴 | Fixed Type Import Issues Preventing Worker Tests | ~308 |
| #36516 | 9:33 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Search Modules | ~377 |
**SessionManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36346 | 8:30 PM | 🔄 | Removed pendingProcessingIds Tracking from Message Iterator | ~306 |
| #36345 | " | 🔄 | Removed pendingProcessingIds Initialization in SessionManager | ~281 |
| #36340 | 8:28 PM | 🔵 | Complete Duplicate Bug Analysis via Explore Agent | ~435 |
| #36333 | 8:27 PM | 🔵 | pendingProcessingIds Tracking Across System | ~357 |
| #36314 | 8:25 PM | 🔵 | Message Queue Processing Duplicate Bug Investigation | ~316 |
**SearchManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36323 | 8:25 PM | 🔵 | Message Queue Architecture Scope Expanded | ~302 |
**OpenRouterAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36214 | 7:30 PM | 🔄 | Refactored OpenRouterAgent to Use Shared Utilities | ~703 |
### Jan 4, 2026
**README.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36942 | 2:43 AM | 🔵 | Recent Context Feature Architecture | ~300 |
**GeminiAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | ✅ | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36914 | 2:24 AM | 🔵 | Recent commit 4d0a10c fixed multiple GitHub issues | ~365 |
| #36845 | 1:44 AM | 🔵 | GeminiAgent Model Configuration and Rate Limiting | ~527 |
| #36829 | 1:40 AM | 🔵 | PR #542 Review Analysis - Multi-Issue Fix Validation | ~562 |
| #36827 | 1:03 AM | ✅ | Branch diff shows 1,293 insertions and 98 deletions across 15 files | ~464 |
| #36790 | 12:49 AM | 🟣 | GitHub Issue #511 Completed - gemini-3-flash Model Support Added | ~482 |
| #36788 | " | 🟣 | Verified gemini-3-flash Three-Location Synchronization | ~331 |
| #36787 | 12:48 AM | 🟣 | Completed gemini-3-flash Support with Runtime Validation | ~382 |
| #36786 | " | 🟣 | Added gemini-3-flash Rate Limit to GEMINI_RPM_LIMITS | ~359 |
| #36785 | " | 🟣 | Added gemini-3-flash Model to GeminiModel Type Union | ~344 |
| #36784 | 12:47 AM | 🔵 | Current Gemini Model Support in GeminiAgent | ~428 |
| #36781 | 12:45 AM | 🔵 | Complete GeminiAgent Model Configuration Gap Analysis | ~552 |
| #36778 | 12:44 AM | 🔵 | GeminiAgent Model Type and RPM Limits Definition | ~395 |
| #36761 | 12:36 AM | ✅ | Created Implementation Plans for Four GitHub Issues | ~507 |
| #36757 | 12:33 AM | 🔵 | Issue #511 Root Cause Identified - Gemini-3-Flash Configuration Mismatch | ~416 |
| #36753 | " | 🔵 | GeminiAgent Implementation Details Examined | ~361 |
**SessionManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36730 | 12:26 AM | ⚖️ | Revised Memory Leak Fix Strategy for Issue #532 | ~412 |
| #36714 | 12:12 AM | 🔵 | Memory Leak Analysis Report for Issue #532 Generated | ~531 |
| #36712 | 12:11 AM | 🔵 | Memory Leak Analysis for Issue #532 Documented | ~646 |
**SDKAgent.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36716 | 12:13 AM | 🔵 | Issue #514 Orphaned .jsonl Session Files Analysis | ~616 |
| #36713 | 12:11 AM | 🔵 | Issue #520 Stuck Messages Already Resolved | ~569 |
### Jan 5, 2026
**SearchManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38080 | 9:55 PM | 🔴 | Critical Date Preservation Fix for Folder CLAUDE.md Timeline Accuracy | ~534 |
| #38036 | 9:43 PM | 🟣 | Configurable Observation Limits and Enhanced Folder Search | ~418 |
| #37979 | 8:33 PM | 🔴 | Fixed date parsing to use API date headers instead of "today" | ~315 |
| #37978 | " | 🔵 | Regenerated CLAUDE.md files across entire repository | ~268 |
| #37970 | 8:31 PM | 🔴 | Fixed Date Parsing Bug in By-File API Endpoint | ~402 |
| #37654 | 5:51 PM | 🔵 | SearchManager imports logger as foundational dependency for search operations | ~358 |
| #37751 | 6:21 PM | 🔴 | OpenRouterAgent Fully Updated with projectRoot Threading | ~307 |
| #37748 | " | | OpenRouterAgent Observation Handler Updated with lastCwd | ~276 |
| #37746 | 6:20 PM | | GeminiAgent Summary Handler Updated with lastCwd | ~278 |
| #37745 | " | | OpenRouterAgent Init Prompt Call Updated with undefined projectRoot | ~299 |
| #37744 | " | | GeminiAgent First processAgentResponse Updated with lastCwd | ~274 |
| #37743 | " | | Added lastCwd Tracking to OpenRouterAgent | ~265 |
| #37742 | 6:19 PM | ✅ | Phase 3 Started: Added lastCwd Tracking to GeminiAgent | ~291 |
| #37741 | " | 🔵 | OpenRouterAgent Structure Analyzed for Phase 3 Implementation | ~367 |
| #37740 | " | 🔵 | SDKAgent Structure Analyzed for Phase 3 Implementation | ~430 |
| #37739 | 6:18 PM | 🔵 | GeminiAgent Structure Analyzed for Phase 3 Implementation | ~381 |
| #37737 | 6:16 PM | 🔵 | Identified processAgentResponse Callers for Phase 3 | ~275 |
| #37701 | 6:01 PM | 🔵 | Complete cwd data flow traced from hooks through observation processing | ~447 |
| #37421 | 1:06 AM | 🔵 | Identified by-file API endpoint usage across codebase | ~406 |
| #37416 | 1:02 AM | 🔴 | Fixed find_by_file Parameter Handling for Comma-Separated Values | ~375 |
| #37415 | " | 🟣 | SearchManager Parameter Normalization Enhanced for Folder Queries | ~406 |
| #37414 | 1:01 AM | 🔵 | SearchManager findByFile Uses filePath Parameter for File Search | ~429 |
| #37413 | " | 🔵 | Hybrid Search Strategy: Metadata-First with Semantic Ranking | ~475 |
| #37391 | 12:48 AM | ✅ | Staged 23 CLAUDE.md files with mix of new and modified content | ~400 |
| #37390 | 12:47 AM | ✅ | Regenerated 23 CLAUDE.md files in budapest workspace | ~365 |
### Jan 7, 2026
**SettingsManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
**DatabaseManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37653 | 5:50 PM | 🔵 | DatabaseManager imports logger demonstrating widespread logger dependency | ~363 |
**SessionManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37626 | 5:35 PM | 🔵 | FormatTool Function Usage Across Codebase | ~493 |
| #37538 | 4:45 PM | 🔵 | SessionManager formatTool Call Occurs After Database Persistence | ~351 |
### Jan 6, 2026
**BranchManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38105 | 12:14 AM | 🔵 | Windows Console Popup Flash Issue Documented and Fixed | ~455 |
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38437 | 10:24 PM | 🔵 | Claude-mem core functionality and logging patterns identified | ~710 |
| #38433 | " | 🔵 | SessionManager Uses ERROR Logging for Database Persistence Failures | ~503 |
| #38431 | " | 🔵 | ERROR-Level Logging Used Across 21 Source Files | ~480 |
| #38425 | " | ⚖️ | Log Level Architecture: Fail-Critical Over Fail-Fast for Chroma | ~467 |
| #38418 | 10:22 PM | 🔵 | ChromaDB Operates as Optional Subsystem with Graceful Degradation | ~586 |
| #38416 | " | 🔵 | ChromaDB Is Critical Not Optional - Log Audit Findings Challenged | ~405 |
| #38405 | 10:07 PM | ⚖️ | DEBUG Log Level Analysis - One Message Requires WARN Promotion | ~819 |
| #38404 | 10:06 PM | ⚖️ | Log Level Audit Analysis - WARN to ERROR Promotion Criteria Established | ~769 |
| #38372 | 9:43 PM | 🔵 | Logging Anti-Pattern Found: Critical Errors Logged as DEBUG Instead of ERROR | ~464 |
| #38354 | 9:10 PM | 🔵 | Provider Selection Architecture and Default Settings Location | ~478 |
| #38353 | " | 🔵 | Session ID Architecture and Message Yielding for SDK Interaction | ~536 |
| #38253 | 7:47 PM | 🔵 | SDK Agent Implementation with Resume Logic | ~1036 |
| #38250 | 7:46 PM | 🔵 | Session Manager Event-Driven Architecture | ~865 |
| #38248 | 7:45 PM | 🔵 | OpenRouter Agent Implementation | ~851 |
</claude-mem-context>

View File

@@ -166,7 +166,7 @@ export class GeminiAgent {
'Gemini'
);
} else {
logger.warn('SDK', 'Empty Gemini init response - session may lack context', {
logger.error('SDK', 'Empty Gemini init response - session may lack context', {
sessionId: session.sessionDbId,
model
});
@@ -355,7 +355,7 @@ export class GeminiAgent {
const data = await response.json() as GeminiResponse;
if (!data.candidates?.[0]?.content?.parts?.[0]?.text) {
logger.warn('SDK', 'Empty response from Gemini');
logger.error('SDK', 'Empty response from Gemini');
return { content: '' };
}

View File

@@ -125,7 +125,7 @@ export class OpenRouterAgent {
undefined // No lastCwd yet - before message processing
);
} else {
logger.warn('SDK', 'Empty OpenRouter init response - session may lack context', {
logger.error('SDK', 'Empty OpenRouter init response - session may lack context', {
sessionId: session.sessionDbId,
model
});
@@ -372,7 +372,7 @@ export class OpenRouterAgent {
}
if (!data.choices?.[0]?.message?.content) {
logger.warn('SDK', 'Empty response from OpenRouter');
logger.error('SDK', 'Empty response from OpenRouter');
return { content: '' };
}

View File

@@ -411,7 +411,7 @@ export class SearchManager {
}
}
} catch (chromaError) {
logger.warn('SEARCH', 'Chroma search failed for timeline, continuing without semantic results', {}, chromaError as Error);
logger.error('SEARCH', 'Chroma search failed for timeline, continuing without semantic results', {}, chromaError as Error);
}
}
@@ -679,7 +679,7 @@ export class SearchManager {
}
}
} catch (chromaError) {
logger.warn('SEARCH', 'Chroma search failed for decisions, falling back to metadata search', {}, chromaError as Error);
logger.error('SEARCH', 'Chroma search failed for decisions, falling back to metadata search', {}, chromaError as Error);
}
}
@@ -747,7 +747,7 @@ export class SearchManager {
}
}
} catch (chromaError) {
logger.warn('SEARCH', 'Chroma search failed for changes, falling back to metadata search', {}, chromaError as Error);
logger.error('SEARCH', 'Chroma search failed for changes, falling back to metadata search', {}, chromaError as Error);
}
}

View File

@@ -3,80 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**ResponseProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36689 | 11:56 PM | 🔵 | PR #538 Review Findings - Modular Architecture Refactor | ~590 |
| #36640 | 10:56 PM | 🔵 | ResponseProcessor Validates memorySessionId Before Storage | ~438 |
| #36352 | 8:32 PM | 🔴 | Fixed Duplicate Observation Storage in ResponseProcessor | ~386 |
| #36340 | 8:28 PM | 🔵 | Complete Duplicate Bug Analysis via Explore Agent | ~435 |
| #36333 | 8:27 PM | 🔵 | pendingProcessingIds Tracking Across System | ~357 |
| #36206 | 7:24 PM | 🟣 | Created ResponseProcessor Module | ~621 |
**FallbackErrorHandler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
| #36627 | 10:44 PM | 🔵 | FallbackErrorHandler Implements Pattern-Based Error Classification | ~445 |
| #36522 | 9:34 PM | 🟣 | Phase 2 Worker Agent Tests Implemented | ~390 |
| #36518 | " | 🟣 | Phase 2 Test Suite Implementation Complete | ~348 |
| #36515 | 9:33 PM | 🟣 | Phase 2 Worker Agents Test Suite Implementation | ~422 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
| #36210 | 7:25 PM | 🟣 | Created FallbackErrorHandler Module | ~533 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36637 | 10:47 PM | 🟣 | GeminiAgent Analysis Agent Running But Timed Out After 120 Seconds | ~521 |
| #36622 | 10:43 PM | 🔵 | Agent Module Architecture Consolidates Shared Functionality | ~396 |
| #36418 | 8:57 PM | 🔄 | Agent Shared Logic Consolidation | ~441 |
| #36211 | 7:26 PM | 🟣 | Created Agent Consolidation Index Module | ~520 |
**index.js**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36525 | 9:34 PM | 🔵 | Test Import Strategy for Avoiding Module Side Effects | ~358 |
| #36521 | " | ⚖️ | Test Import Strategy: Direct Imports Over Barrel Exports | ~321 |
**ObservationBroadcaster.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36443 | 9:01 PM | 🔴 | SSE Broadcasting Field Name Corrections | ~405 |
| #36207 | 7:24 PM | 🟣 | Created ObservationBroadcaster Module | ~480 |
**SessionCleanupHelper.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36441 | 9:01 PM | 🔵 | Session Cleanup with Claim-and-Delete Queue Pattern | ~393 |
| #36323 | 8:25 PM | 🔵 | Message Queue Architecture Scope Expanded | ~302 |
| #36314 | " | 🔵 | Message Queue Processing Duplicate Bug Investigation | ~316 |
| #36208 | 7:25 PM | 🟣 | Created SessionCleanupHelper Module | ~527 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36432 | 9:00 PM | 🔵 | Agent Types Support Testing Without Worker Context | ~378 |
| #36201 | 7:23 PM | 🟣 | Created Shared Agent Types Module | ~565 |
### Jan 4, 2026
**ResponseProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36712 | 12:11 AM | 🔵 | Memory Leak Analysis for Issue #532 Documented | ~646 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**ResponseProcessor.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38051 | 9:46 PM | 🔵 | Live Context Integration in ResponseProcessor | ~523 |
| #37999 | 9:02 PM | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
*No recent activity*
</claude-mem-context>

View File

@@ -185,7 +185,7 @@ async function syncAndBroadcastObservations(
title: obs.title || '(untitled)'
});
}).catch((error) => {
logger.warn('CHROMA', `${agentName} chroma sync failed, continuing without vector search`, {
logger.error('CHROMA', `${agentName} chroma sync failed, continuing without vector search`, {
obsId,
type: obs.type,
title: obs.title || '(untitled)'
@@ -269,7 +269,7 @@ async function syncAndBroadcastSummary(
request: summaryForStore.request || '(no request)'
});
}).catch((error) => {
logger.warn('CHROMA', `${agentName} chroma sync failed, continuing without vector search`, {
logger.error('CHROMA', `${agentName} chroma sync failed, continuing without vector search`, {
summaryId: result.summaryId,
request: summaryForStore.request || '(no request)'
}, error);

View File

@@ -3,56 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 28, 2025
**BaseRouteHandler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33396 | 9:53 PM | ✅ | Queue refactoring touched 12 files with net addition of 1021 lines | ~402 |
| #33336 | 3:36 PM | 🔴 | Fixed Windows Worker Crashes and Headers Already Sent Errors | ~351 |
| #33259 | 2:46 PM | 🔴 | Windows Worker Stability Pull Request Created | ~386 |
| #33258 | 2:38 PM | 🔴 | Added headersSent Guard to Error Handler | ~338 |
| #33256 | 2:36 PM | ⚖️ | Implementation Plan for Windows Worker Issues | ~471 |
### Jan 1, 2026
**middleware.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35614 | 10:57 PM | 🔴 | Suppressed /api/logs endpoint logging to reduce noise | ~252 |
| #35612 | " | ✅ | HTTP logging middleware excludes /api/logs polling endpoint | ~262 |
| #35611 | " | 🔵 | HTTP Middleware Architecture in Worker Service | ~360 |
**BaseRouteHandler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35433 | 8:43 PM | 🔵 | Try-Catch Block Distribution Across Services | ~372 |
### Jan 2, 2026
**middleware.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
### Jan 3, 2026
**middleware.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36689 | 11:56 PM | 🔵 | PR #538 Review Findings - Modular Architecture Refactor | ~590 |
### Jan 5, 2026
**BaseRouteHandler.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
| #37662 | " | 🔵 | BaseRouteHandler imports logger demonstrating HTTP layer dependency on logger | ~367 |
**middleware.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37626 | 5:35 PM | 🔵 | FormatTool Function Usage Across Codebase | ~493 |
| #37537 | 4:45 PM | 🔵 | Middleware formatTool Call Confirmed as Critical Crash Point | ~361 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,105 +3,57 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
**SessionRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36103 | 10:25 PM | 🟣 | Generator Crash Recovery with Automatic Restart | ~374 |
| #36079 | 10:10 PM | 🔴 | Fixed Generator Crashes from Silent Chroma Vector Search Failures | ~531 |
| #36066 | 9:55 PM | 🔵 | Session Generator Lifecycle and Error Handling Architecture | ~536 |
| #36008 | 8:15 PM | 🔴 | Fixed Memory Leak in Generator Error Handler | ~358 |
| #36007 | " | 🔵 | Generator Error Handler Missing pendingProcessingIds Clear | ~376 |
| #35998 | 5:32 PM | 🔴 | Critical Session ID Placeholder Bug Fixed to Prevent Transcript Pollution | ~488 |
| #35997 | " | 🟣 | Session Alignment Logging Implemented Across Hook, HTTP, and SDK Layers | ~342 |
| #35994 | 5:18 PM | 🔄 | Session Alignment Logging Updated to Track Memory ID Capture Status | ~334 |
| #35985 | 5:16 PM | 🔵 | Alignment logging implemented across session lifecycle touchpoints | ~377 |
| #35977 | 4:48 PM | 🔵 | Existing alignment logging infrastructure found | ~353 |
| #35971 | 4:47 PM | 🟣 | Added Session Alignment Logging to Session Initialization | ~349 |
| #35970 | " | 🔵 | Session ID Logging Distribution Across Codebase | ~485 |
| #35968 | 4:46 PM | 🔵 | Content-Session API Endpoint Registration | ~280 |
| #35967 | " | 🔵 | Content-Session-Based Observation and Summarize Endpoints with Privacy and Tool Filtering | ~607 |
| #35966 | 4:45 PM | 🔵 | Session Initialization Stage One - Database Setup with Privacy Filtering | ~554 |
| #35964 | " | 🔵 | Session Initialization Two-Stage API Pattern | ~468 |
| #35963 | " | 🔵 | Session Route Endpoints and Crash Recovery Logic | ~634 |
| #35962 | " | 🔵 | Session ID Usage Pattern Distribution | ~309 |
| #35961 | 4:44 PM | 🔵 | SessionRoutes Multi-Provider Agent Selection | ~575 |
| #35936 | 2:56 PM | 🔵 | SessionRoutes Has Catch Block That Marks Failed Messages After Generator Crashes | ~437 |
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #35854 | 2:32 PM | 🔵 | Generator Error Handler Marks Processing Messages as Failed | ~505 |
**SearchRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35951 | 4:42 PM | 🔵 | Multi-Layer Service Architecture Discovery | ~395 |
**LogsRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35875 | 2:39 PM | 🔵 | Logging UI Architecture Mapped | ~599 |
| #35826 | 2:29 PM | 🔵 | Backend logs API implementation analyzed | ~284 |
### Jan 3, 2026
**SessionRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36333 | 8:27 PM | 🔵 | pendingProcessingIds Tracking Across System | ~357 |
| #36323 | 8:25 PM | 🔵 | Message Queue Architecture Scope Expanded | ~302 |
### Jan 4, 2026
**SearchRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36942 | 2:43 AM | 🔵 | Recent Context Feature Architecture | ~300 |
**SettingsRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36781 | 12:45 AM | 🔵 | Complete GeminiAgent Model Configuration Gap Analysis | ~552 |
| #36768 | 12:42 AM | 🔵 | Gemini Model Validation in SettingsRoutes | ~397 |
| #36757 | 12:33 AM | 🔵 | Issue #511 Root Cause Identified - Gemini-3-Flash Configuration Mismatch | ~416 |
| #36755 | " | 🔵 | SettingsRoutes Validation Includes gemini-3-flash | ~344 |
| #36754 | " | 🔵 | Gemini-3-Flash Model Already Supported | ~301 |
**SessionRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36730 | 12:26 AM | ⚖️ | Revised Memory Leak Fix Strategy for Issue #532 | ~412 |
| #36714 | 12:12 AM | 🔵 | Memory Leak Analysis Report for Issue #532 Generated | ~531 |
| #36712 | 12:11 AM | 🔵 | Memory Leak Analysis for Issue #532 Documented | ~646 |
| #37327 | 11:44 PM | | Cleaned Up Auto-Generated CLAUDE.md Files | ~352 |
| #37326 | " | ✅ | Staged All Changes for Commit | ~386 |
| #37325 | " | ✅ | Staged PR #554 Implementation Files | ~373 |
| #37324 | " | | Cleaned Up Auto-Generated CLAUDE.md Files | ~392 |
| #37323 | " | ✅ | Cleanup Completed - 31 Auto-Generated CLAUDE.md Files Deleted | ~411 |
| #37286 | 11:07 PM | | Phase 1 Settings Patch Applied Successfully | ~249 |
| #37282 | 11:06 PM | | Phase 1 Settings Patch Created | ~284 |
| #37280 | " | 🔵 | Feature Branch Missing FOLDER_CLAUDEMD_ENABLED Setting | ~251 |
| #37272 | 11:02 PM | | Phase 1 Verification Complete - All Checks Pass | ~275 |
| #37270 | " | 🔵 | Settings Routes Already Include FOLDER_CLAUDEMD_ENABLED | ~333 |
| #37267 | 11:00 PM | ✅ | Added CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED to Settings Validation | ~284 |
| #37266 | 10:59 PM | 🟣 | Added FOLDER_CLAUDEMD_ENABLED to Settings Routes Handler | ~329 |
| #37259 | 10:32 PM | ⚖️ | Implementation Plan Created for PR #554 Enhancements | ~621 |
| #37258 | 10:31 PM | ⚖️ | Comprehensive Implementation Plan Created for PR #554 Review Fixes | ~722 |
| #37257 | 10:29 PM | 🔵 | Regenerate Script and Settings Infrastructure Analyzed | ~563 |
| #37255 | " | 🔵 | Folder CLAUDE.md Integration Flow Mapped | ~550 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
| #37947 | 8:10 PM | 🔵 | Context injection generates formatted context via generateContext function | ~332 |
| #37838 | 6:55 PM | 🔵 | Complete Hook Architecture Technical Specification | ~704 |
| #37836 | 6:54 PM | 🔵 | Worker Service HTTP API Architecture and Hook Integration Pattern | ~639 |
| #37702 | 6:01 PM | 🔵 | Codebase uses path.join() exclusively with known anchors, no project root resolution pattern exists | ~489 |
| #37701 | " | 🔵 | Complete cwd data flow traced from hooks through observation processing | ~447 |
| #37694 | 5:55 PM | 🔵 | Sessions initialized via SessionManager.initializeSession() with cwd from request body | ~361 |
| #37440 | 1:13 AM | 🔵 | Comprehensive Analysis of Settings and Hard-Coded Limit | ~389 |
| #37435 | " | 🔵 | Settings Validation Limits CLAUDE_MEM_CONTEXT_OBSERVATIONS to 1-200 | ~307 |
| #37421 | 1:06 AM | 🔵 | Identified by-file API endpoint usage across codebase | ~406 |
| #37408 | 12:58 AM | 🔵 | SearchRoutes API Architecture with Worktree Support | ~543 |
| #37391 | 12:48 AM | ✅ | Staged 23 CLAUDE.md files with mix of new and modified content | ~400 |
| #37390 | 12:47 AM | ✅ | Regenerated 23 CLAUDE.md files in budapest workspace | ~365 |
**SearchRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38076 | 9:53 PM | 🟣 | Worktree-Aware Project Filtering for Unified Timeline Context | ~578 |
| #38072 | 9:52 PM | ✅ | Worktree Support Added to Context Injection API | ~526 |
### Jan 7, 2026
**SessionRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37999 | 9:02 PM | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
| #37758 | 6:25 PM | ⚖️ | Integration Test Design for Four Critical Testing Gaps | ~729 |
**SettingsRoutes.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37997 | 9:01 PM | 🔵 | SettingsRoutes validation pattern for CLAUDE_MEM_WORKER_HOST | ~320 |
| #37995 | " | 🔵 | CLAUDE_MEM_WORKER_HOST setting implementation pattern | ~304 |
| #37990 | 9:00 PM | 🔵 | CLAUDE_MEM_WORKER_HOST setting used across 19 files | ~289 |
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
| #37651 | 5:50 PM | 🔵 | SettingsRoutes uses both logger and SettingsDefaultsManager creating circular dependency exposure | ~404 |
| #37592 | 4:56 PM | ✅ | Phase 3 Anti-Pattern Check Complete - Clean Implementation | ~434 |
| #37548 | 4:48 PM | ✅ | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
| #37547 | 4:47 PM | ✅ | Issue #557 Analysis Report Created for Plugin Startup Failure | ~491 |
| #37543 | " | 🔵 | Settings File Auto-Creation Logic Found in SettingsRoutes | ~463 |
| #38467 | 10:29 PM | ⚖️ | Log Level Audit Strategy: Tighten ERROR Messages for Runtime Issue Discovery | ~464 |
| #38456 | 10:26 PM | 🔵 | happyPathError Inline Fallback: Missing CWD When Queueing Observations | ~463 |
| #38453 | " | 🔵 | Generator Exit Patterns: Distinguishing Aborts from Unexpected Failures | ~454 |
| #38437 | 10:24 PM | 🔵 | Claude-mem core functionality and logging patterns identified | ~710 |
| #38431 | " | 🔵 | ERROR-Level Logging Used Across 21 Source Files | ~480 |
| #38405 | 10:07 PM | ⚖️ | DEBUG Log Level Analysis - One Message Requires WARN Promotion | ~819 |
| #38404 | 10:06 PM | ⚖️ | Log Level Audit Analysis - WARN to ERROR Promotion Criteria Established | ~769 |
| #38372 | 9:43 PM | 🔵 | Logging Anti-Pattern Found: Critical Errors Logged as DEBUG Instead of ERROR | ~464 |
| #38356 | 9:16 PM | 🔴 | Fixed AbortController Leak During Crash Recovery | ~384 |
| #38354 | 9:10 PM | 🔵 | Provider Selection Architecture and Default Settings Location | ~478 |
| #38351 | 9:09 PM | 🔵 | AbortController Replacement Without Abort Confirmed at Line 191 | ~434 |
</claude-mem-context>

View File

@@ -150,7 +150,7 @@ export class SessionRoutes extends BaseRouteHandler {
try {
const failedCount = pendingStore.markSessionMessagesFailed(session.sessionDbId);
if (failedCount > 0) {
logger.warn('SESSION', `Marked messages as failed after generator error`, {
logger.error('SESSION', `Marked messages as failed after generator error`, {
sessionId: session.sessionDbId,
failedCount
});
@@ -168,7 +168,7 @@ export class SessionRoutes extends BaseRouteHandler {
if (wasAborted) {
logger.info('SESSION', `Generator aborted`, { sessionId: sessionDbId });
} else {
logger.warn('SESSION', `Generator exited unexpectedly`, { sessionId: sessionDbId });
logger.error('SESSION', `Generator exited unexpectedly`, { sessionId: sessionDbId });
}
session.generatorPromise = null;
@@ -187,8 +187,10 @@ export class SessionRoutes extends BaseRouteHandler {
pendingCount
});
// Create new AbortController for the restarted generator
// Abort OLD controller before replacing to prevent child process leaks
const oldController = session.abortController;
session.abortController = new AbortController();
oldController.abort();
// Small delay before restart
setTimeout(() => {
@@ -282,7 +284,7 @@ export class SessionRoutes extends BaseRouteHandler {
prompt: truncatedPrompt
});
}).catch((error) => {
logger.warn('CHROMA', 'User prompt sync failed, continuing without vector search', {
logger.error('CHROMA', 'User prompt sync failed, continuing without vector search', {
promptId: latestPrompt.id,
prompt: promptText.length > 60 ? promptText.substring(0, 60) + '...' : promptText
}, error);
@@ -466,13 +468,13 @@ export class SessionRoutes extends BaseRouteHandler {
tool_input: cleanedToolInput,
tool_response: cleanedToolResponse,
prompt_number: promptNumber,
cwd: cwd || logger.happyPathError(
'SESSION',
'Missing cwd when queueing observation in SessionRoutes',
{ sessionId: sessionDbId },
{ tool_name },
''
)
cwd: cwd || (() => {
logger.error('SESSION', 'Missing cwd when queueing observation in SessionRoutes', {
sessionId: sessionDbId,
tool_name
});
return '';
})()
});
// Ensure SDK agent is running

View File

@@ -3,46 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**ResultFormatter.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
| #36540 | 9:39 PM | 🟣 | ResultFormatter Test Suite Created | ~424 |
| #36533 | 9:35 PM | 🔵 | ResultFormatter for Unified Search Result Display | ~598 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**SearchOrchestrator.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36545 | 9:41 PM | 🟣 | Phase 3 Search Strategy Test Suite Completion | ~564 |
| #36544 | 9:40 PM | 🟣 | Phase 3 Search Strategy Test Suite Complete | ~449 |
| #36543 | " | 🟣 | Phase 3 Search Strategy Tests Completed | ~458 |
| #36541 | 9:39 PM | 🟣 | SearchOrchestrator Test Suite Implementation | ~588 |
| #36531 | 9:34 PM | 🔵 | SearchOrchestrator Strategy Selection Logic | ~334 |
| #36529 | " | 🔵 | Search Module Architecture Discovery | ~302 |
**types.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36538 | 9:38 PM | 🟣 | SQLiteSearchStrategy Test Suite Created | ~527 |
| #36537 | " | 🟣 | HybridSearchStrategy Test Suite Created | ~435 |
| #36536 | " | 🟣 | ChromaSearchStrategy Test Suite Created | ~430 |
| #36523 | 9:34 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Services | ~386 |
| #36519 | " | 🔴 | Fixed Type Import Issues Preventing Worker Tests | ~308 |
| #36516 | 9:33 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Search Modules | ~377 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36527 | 9:34 PM | 🔵 | Search Strategy Architecture Analysis for Phase 3 Testing | ~486 |
| #36421 | 8:58 PM | 🔄 | Search Module Public API Organization | ~393 |
### Jan 5, 2026
**ResultFormatter.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37968 | 8:22 PM | 🔵 | ResultFormatter Uses Epoch Timestamps from Database | ~364 |
*No recent activity*
</claude-mem-context>

View File

@@ -3,43 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**SearchStrategy.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36670 | 11:37 PM | ✅ | Resolved merge conflicts by accepting branch changes for 39 files | ~435 |
| #36534 | 9:35 PM | 🔵 | SearchStrategy Interface Pattern | ~341 |
| #36523 | 9:34 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Services | ~386 |
| #36519 | " | 🔴 | Fixed Type Import Issues Preventing Worker Tests | ~308 |
| #36516 | 9:33 PM | 🔴 | Fixed TypeScript Type Import Issues in Worker Search Modules | ~377 |
| #36449 | 9:02 PM | 🔵 | Search Strategy Base Implementation | ~410 |
| #36419 | 8:57 PM | 🔵 | Search Strategy Interface Pattern | ~380 |
**SQLiteSearchStrategy.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36545 | 9:41 PM | 🟣 | Phase 3 Search Strategy Test Suite Completion | ~564 |
| #36544 | 9:40 PM | 🟣 | Phase 3 Search Strategy Test Suite Complete | ~449 |
| #36538 | 9:38 PM | 🟣 | SQLiteSearchStrategy Test Suite Created | ~527 |
| #36527 | 9:34 PM | 🔵 | Search Strategy Architecture Analysis for Phase 3 Testing | ~486 |
| #36526 | " | 🔵 | SQLite Search Strategy Architecture | ~439 |
| #36451 | 9:02 PM | 🔵 | SQLite Search Strategy Implementation | ~453 |
**ChromaSearchStrategy.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36543 | 9:40 PM | 🟣 | Phase 3 Search Strategy Tests Completed | ~458 |
| #36536 | 9:38 PM | 🟣 | ChromaSearchStrategy Test Suite Created | ~430 |
| #36530 | 9:34 PM | 🔵 | Chroma Vector Search Strategy Architecture | ~508 |
| #36529 | " | 🔵 | Search Module Architecture Discovery | ~302 |
| #36390 | 8:50 PM | 🔄 | Comprehensive Monolith Refactor with Modular Architecture | ~724 |
**HybridSearchStrategy.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36537 | 9:38 PM | 🟣 | HybridSearchStrategy Test Suite Created | ~435 |
| #36532 | 9:34 PM | 🔵 | HybridSearchStrategy Four-Step Pattern | ~333 |
| #36528 | " | 🔵 | Hybrid Search Strategy Combining Metadata Filtering with Semantic Ranking | ~525 |
| #36459 | 9:03 PM | 🔵 | Hybrid Search Strategy with Four-Step Algorithm | ~530 |
*No recent activity*
</claude-mem-context>

View File

@@ -138,7 +138,7 @@ export class ChromaSearchStrategy extends BaseSearchStrategy implements SearchSt
};
} catch (error) {
logger.warn('SEARCH', 'ChromaSearchStrategy: Search failed', {}, error as Error);
logger.error('SEARCH', 'ChromaSearchStrategy: Search failed', {}, error as Error);
// Return empty result - caller may try fallback strategy
return {
results: { observations: [], sessions: [], prompts: [] },

View File

@@ -111,7 +111,7 @@ export class HybridSearchStrategy extends BaseSearchStrategy implements SearchSt
return this.emptyResult('hybrid');
} catch (error) {
logger.warn('SEARCH', 'HybridSearchStrategy: findByConcept failed', {}, error as Error);
logger.error('SEARCH', 'HybridSearchStrategy: findByConcept failed', {}, error as Error);
// Fall back to metadata-only results
const results = this.sessionSearch.findByConcept(concept, filterOptions);
return {
@@ -176,7 +176,7 @@ export class HybridSearchStrategy extends BaseSearchStrategy implements SearchSt
return this.emptyResult('hybrid');
} catch (error) {
logger.warn('SEARCH', 'HybridSearchStrategy: findByType failed', {}, error as Error);
logger.error('SEARCH', 'HybridSearchStrategy: findByType failed', {}, error as Error);
const results = this.sessionSearch.findByType(type as any, filterOptions);
return {
results: { observations: results, sessions: [], prompts: [] },
@@ -242,7 +242,7 @@ export class HybridSearchStrategy extends BaseSearchStrategy implements SearchSt
return { observations: [], sessions, usedChroma: false };
} catch (error) {
logger.warn('SEARCH', 'HybridSearchStrategy: findByFile failed', {}, error as Error);
logger.error('SEARCH', 'HybridSearchStrategy: findByFile failed', {}, error as Error);
const results = this.sessionSearch.findByFile(filePath, filterOptions);
return {
observations: results.observations,

View File

@@ -97,7 +97,7 @@ export class SQLiteSearchStrategy extends BaseSearchStrategy implements SearchSt
};
} catch (error) {
logger.warn('SEARCH', 'SQLiteSearchStrategy: Search failed', {}, error as Error);
logger.error('SEARCH', 'SQLiteSearchStrategy: Search failed', {}, error as Error);
return this.emptyResult('sqlite');
}
}

View File

@@ -3,117 +3,113 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
### Nov 10, 2025
**SettingsDefaultsManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35965 | 4:45 PM | | Removed Session Alignment Debug Mode Setting | ~249 |
| #6295 | 1:18 PM | 🔵 | Path Configuration Structure for claude-mem | ~305 |
### Dec 5, 2025
**worker-utils.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35900 | 2:49 PM | 🔵 | Worker Health Checks Use Fetch Without Timeout Configuration | ~397 |
| #20730 | 9:06 PM | 🔵 | Path Configuration Module with ESM/CJS Compatibility | ~578 |
| #20718 | 9:00 PM | 🔵 | Worker Service Auto-Start and Health Check System | ~448 |
| #20410 | 7:21 PM | 🔵 | Path utilities provide cross-runtime directory management with Claude integration support | ~478 |
| #20409 | 7:20 PM | 🔵 | Worker utilities provide automatic PM2 startup with health checking and port configuration | ~479 |
### Dec 9, 2025
**paths.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #23141 | 6:42 PM | 🔵 | Located getSettingsPath Function in paths.ts | ~261 |
| #23134 | 6:41 PM | ✅ | Set CLAUDE_MEM_SKIP_TOOLS Default Value in SettingsDefaultsManager | ~261 |
| #23133 | " | ✅ | Added CLAUDE_MEM_SKIP_TOOLS to SettingsDefaults Interface | ~231 |
| #23131 | 6:40 PM | 🔵 | SettingsDefaultsManager Structure and Configuration Schema | ~363 |
| #22858 | 2:28 PM | 🔄 | Removed Brittle save.md Validation from paths.ts | ~305 |
| #22852 | 2:26 PM | 🔵 | Located save.md Validation Logic in paths.ts | ~255 |
| #22805 | 2:01 PM | 🔵 | Early Settings Silent Failure Point Identified | ~363 |
| #22803 | " | 🔵 | Worker Utilities Current Implementation Review | ~390 |
| #22518 | 12:59 AM | 🔵 | Worker Utils StartWorker Implementation Uses Plugin Root for PM2 | ~311 |
### Dec 10, 2025
**hook-constants.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35890 | 2:47 PM | 🔵 | Hook Exit Codes Define Three States But Not All Hooks Use Them | ~362 |
| #35865 | 2:35 PM | 🔵 | Hook Constants Define Timeouts and Exit Codes | ~445 |
| #23831 | 11:15 PM | 🔵 | Current hook-error-handler.ts References PM2 | ~277 |
| #23830 | " | 🔵 | Current worker-utils.ts Implementation Uses PM2 | ~431 |
| #23812 | 10:49 PM | 🔵 | Current Worker Startup Uses PM2 and PowerShell; Phase 2 Will Replace | ~428 |
| #23811 | " | 🔵 | Existing Paths Configuration for Phase 2 Reference | ~297 |
### Dec 12, 2025
**transcript-parser.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35746 | 1:17 PM | 🔵 | Transcript Parser extractLastMessage Implementation Examined | ~423 |
| #24405 | 8:12 PM | 🔵 | PM2 Legacy Cleanup Migration in Worker Startup | ~303 |
| #24400 | 8:10 PM | 🔵 | Retrieved PM2 Cleanup Implementation Details from Memory | ~355 |
| #24362 | 7:00 PM | 🟣 | Implemented PM2 Cleanup One-Time Marker in worker-utils.ts | ~376 |
| #24361 | " | ✅ | Added File System Imports to worker-utils.ts for PM2 Marker | ~263 |
| #24360 | " | 🔵 | worker-utils.ts Contains PM2 Cleanup Logic Without One-Time Marker | ~390 |
### Jan 4, 2026
### Dec 13, 2025
**SettingsDefaultsManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36781 | 12:45 AM | 🔵 | Complete GeminiAgent Model Configuration Gap Analysis | ~552 |
| #36757 | 12:33 AM | 🔵 | Issue #511 Root Cause Identified - Gemini-3-Flash Configuration Mismatch | ~416 |
| #36754 | " | 🔵 | Gemini-3-Flash Model Already Supported | ~301 |
| #25088 | 7:18 PM | 🟣 | Added CLAUDE_MEM_EMBEDDING_FUNCTION to Settings Interface | ~269 |
### Jan 5, 2026
### Dec 14, 2025
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38082 | 10:13 PM | | Merge Conflict Resolution - Kept Feature Branch Versions | ~431 |
| #38078 | 9:54 PM | | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
| #26790 | 11:38 PM | 🔴 | Fixed Undefined Port Variable in Error Logger | ~340 |
| #26789 | " | 🔴 | Fixed Undefined Port Variable in Error Logging | ~316 |
| #26788 | " | 🔵 | Worker Utils Already Imports Required Dependencies for Implementation | ~283 |
| #26787 | " | 🟣 | Phase 2 Complete: Pre-Restart Delay Added to Version Mismatch Handler | ~436 |
| #26786 | " | 🟣 | Phase 2 Complete: Pre-Restart Delay Added to ensureWorkerVersionMatches Function | ~420 |
| #26785 | 11:37 PM | 🟣 | Phase 1 Complete: PRE_RESTART_SETTLE_DELAY Constant Added to Hook Timeouts | ~351 |
| #26784 | " | 🟣 | Phase 1 Complete: PRE_RESTART_SETTLE_DELAY Constant Added to HOOK_TIMEOUTS | ~370 |
| #26783 | " | 🔵 | Hook Constants File Defines Timeout Values and Platform Multiplier | ~452 |
| #26782 | " | 🔵 | hook-constants.ts Defines Timeout Constants With Windows Platform Multiplier | ~418 |
| #26766 | 11:30 PM | ⚖️ | Root Cause Identified: Missing Post-Install Worker Restart Trigger in Plugin Update Flow | ~604 |
| #26765 | " | 🔵 | Explore Agent Confirms Root Cause: No Proactive Worker Restart After Plugin Updates | ~613 |
| #26732 | 11:25 PM | 🔵 | Worker Utils Implements Version Mismatch Detection and Auto-Restart | ~516 |
| #26731 | 11:24 PM | 🔵 | ensureWorkerRunning Implementation Shows 2.5 Second Startup Wait With Version Check | ~522 |
| #25695 | 4:27 PM | 🟣 | Added comprehensive error logging to transcript parser for debugging message extraction failures | ~473 |
| #25693 | 4:24 PM | 🔵 | Transcript parser extracts messages from JSONL file by scanning backwards for role-specific entries | ~491 |
### Dec 17, 2025
**SettingsDefaultsManager.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38064 | 9:50 PM | ⚖️ | 9.0 Release Documentation Audit Complete - Major Gaps Identified | ~997 |
| #38055 | 9:47 PM | 🔵 | SettingsDefaultsManager Missing CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED Setting | ~549 |
| #38048 | 9:45 PM | 🔴 | PR #558 - Comprehensive Bug Fix and Test Quality Improvement | ~585 |
| #38005 | 9:03 PM | 🔵 | Comprehensive exploration of PR review items completed | ~438 |
| #37996 | 9:01 PM | 🔵 | SettingsDefaultsManager provides centralized settings management | ~310 |
| #37995 | " | 🔵 | CLAUDE_MEM_WORKER_HOST setting implementation pattern | ~304 |
| #37990 | 9:00 PM | 🔵 | CLAUDE_MEM_WORKER_HOST setting used across 19 files | ~289 |
| #37887 | 7:32 PM | ✅ | Added Cross-Reference Comment for DEFAULT_DATA_DIR Constant | ~361 |
| #37881 | 7:31 PM | 🔵 | SettingsDefaultsManager Implementation Details Examined | ~384 |
| #37785 | 6:37 PM | 🔴 | Completed Removal of All Logger References from SettingsDefaultsManager | ~315 |
| #37784 | " | 🔄 | Replaced Logger Calls with Console Logging in SettingsDefaultsManager | ~331 |
| #37783 | " | 🔄 | Removed Logger Import from SettingsDefaultsManager | ~323 |
| #37779 | 6:36 PM | 🔵 | SettingsDefaultsManager Uses Logger Methods | ~375 |
| #37774 | 6:35 PM | 🔵 | Circular Dependency Between Logger and SettingsDefaultsManager | ~326 |
| #37773 | " | 🔵 | SettingsDefaultsManager Uses Logger Import | ~267 |
| #37665 | 5:52 PM | 🔵 | Codebase uses dependency injection and lazy initialization patterns to avoid circular dependencies | ~548 |
| #37632 | 5:37 PM | 🔵 | SettingsDefaultsManager Circular Dependency with Logger Confirmed | ~556 |
| #37628 | 5:36 PM | 🔴 | Test Execution Shows Logger Circular Dependency Error | ~596 |
| #37617 | 5:32 PM | ⚖️ | PR #558 Review Requirements Categorized by Priority | ~637 |
| #37613 | 5:31 PM | 🔵 | PR #558 Review Feedback Analysis | ~544 |
| #37593 | 4:56 PM | 🟣 | Phase 3 Committed - Settings Auto-Creation Implemented | ~386 |
| #37592 | " | ✅ | Phase 3 Anti-Pattern Check Complete - Clean Implementation | ~434 |
| #37590 | 4:55 PM | 🟣 | Phase 3 Complete - Settings Auto-Creation Implemented | ~400 |
| #37589 | " | 🟣 | Implemented Settings File Auto-Creation in loadFromFile | ~385 |
| #37588 | " | ✅ | Added Required Imports for Settings File Creation | ~291 |
| #37587 | 4:54 PM | 🔵 | SettingsDefaultsManager Missing File Auto-Creation | ~374 |
| #37548 | 4:48 PM | ✅ | Issue #543 Analysis Report Created for Slash Command Availability | ~540 |
| #37547 | 4:47 PM | ✅ | Issue #557 Analysis Report Created for Plugin Startup Failure | ~491 |
| #37535 | 4:44 PM | 🔵 | Settings Defaults Manager Implementation Analysis | ~447 |
| #28464 | 4:25 PM | 🔵 | Platform-Adjusted Hook Timeout Configuration | ~468 |
| #28461 | " | 🔵 | Dual ESM/CJS Path Resolution System | ~479 |
| #28452 | 4:23 PM | 🔵 | Worker Version Matching and Auto-Restart System | ~510 |
### Dec 18, 2025
**worker-utils.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38012 | 9:12 PM | | Completed Phase 1: Added getWorkerHost() import and replaced hard-coded localhost | ~319 |
| #38000 | 9:02 PM | 🔵 | Mixed usage of hard-coded 127.0.0.1 vs getWorkerHost() | ~347 |
| #37999 | " | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
| #37998 | " | 🔵 | worker-utils.ts provides cached host and port accessors | ~360 |
| #29797 | 7:09 PM | 🔵 | Settings System Uses CLAUDE_MEM_MODE for Mode Selection | ~353 |
| #29234 | 12:10 AM | 🔵 | Centralized Settings Management with Environment Defaults | ~394 |
### Dec 20, 2025
**timeline-formatting.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37967 | 8:21 PM | 🔵 | Timeline Formatting Utilities Provide Correct Date Functions | ~384 |
| #31086 | 7:59 PM | 🔵 | Transcript Parser Extracts Messages from JSONL Hook Files | ~327 |
| #30939 | 6:57 PM | 🔵 | Worker Utils File Examined for Error Handling Inconsistency | ~393 |
| #30855 | 6:22 PM | 🔵 | Transcript Parser Content Format Handling Examined | ~406 |
### Dec 25, 2025
**hook-constants.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37558 | 4:49 PM | 🔵 | Issue #555 Windows Hook Execution Patterns and Fix Strategy Documented | ~510 |
| #37552 | 4:48 PM | 🔵 | Hook Timeout Configuration and Windows Multiplier | ~352 |
| #32616 | 8:43 PM | 🔵 | Comprehensive analysis of "enable billing" setting and its impact on rate limiting | ~533 |
| #32538 | 7:28 PM | | Set default Gemini billing to disabled | ~164 |
### Jan 7, 2026
**paths.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37536 | 4:44 PM | 🔵 | Path Configuration and Directory Initialization Logic | ~430 |
### Jan 6, 2026
**worker-utils.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38108 | 12:15 AM | 🔵 | Complete Windows Zombie Port Bug Technical Deep Dive | ~935 |
**hook-constants.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
| #38175 | 7:26 PM | 🔵 | Complete Claude-Mem Hook Output Architecture Documented | ~530 |
</claude-mem-context>

View File

@@ -9,12 +9,17 @@ export const HOOK_TIMEOUTS = {
/**
* Hook exit codes for Claude Code
*
* Exit code behavior per Claude Code docs:
* - 0: Success. For SessionStart/UserPromptSubmit, stdout added to context.
* - 2: Blocking error. For SessionStart, stderr shown to user only.
* - Other non-zero: stderr shown in verbose mode only.
*/
export const HOOK_EXIT_CODES = {
SUCCESS: 0,
FAILURE: 1,
/** Show user message that Claude does NOT receive as context */
USER_MESSAGE_ONLY: 3,
/** Blocking error - for SessionStart, shows stderr to user only */
BLOCKING_ERROR: 2,
} as const;
export function getTimeout(baseTimeout: number): number {

View File

@@ -3,81 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 5, 2026
**claude-md-utils.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38086 | 10:42 PM | ✅ | Merged PR with comprehensive CLAUDE.md documentation system | ~478 |
| #38080 | 9:55 PM | 🔴 | Critical Date Preservation Fix for Folder CLAUDE.md Timeline Accuracy | ~534 |
| #38049 | 9:46 PM | 🔵 | Live Context Core Implementation in claude-md-utils.ts | ~585 |
| #38047 | 9:45 PM | 🔴 | PR #556 Review Items - Worker Host Configuration and Path Resolution | ~389 |
| #38025 | 9:15 PM | 🔴 | Fixed PR #556 review items and committed changes | ~344 |
| #38024 | " | ✅ | Git status shows modified source files and auto-updated CLAUDE.md files | ~295 |
| #38022 | " | ✅ | Phase 3 complete: Worktree detection test coverage verified by agent | ~391 |
| #38015 | 9:13 PM | 🔴 | Enhanced error logging with message and stack trace details | ~313 |
| #38014 | " | ✅ | Enhanced error logging with message and stack details | ~309 |
| #38013 | 9:12 PM | ✅ | Verified removal of hard-coded localhost from claude-md-utils.ts | ~209 |
| #38012 | " | ✅ | Completed Phase 1: Added getWorkerHost() import and replaced hard-coded localhost | ~319 |
| #38011 | " | 🔴 | Fixed hard-coded localhost in claude-md-utils.ts | ~281 |
| #38010 | " | ✅ | Replaced hard-coded 127.0.0.1 with getWorkerHost() in claude-md-utils.ts | ~270 |
| #38009 | " | 🔴 | Added getWorkerHost import to claude-md-utils.ts | ~246 |
| #38005 | 9:03 PM | 🔵 | Comprehensive exploration of PR review items completed | ~438 |
| #37993 | 9:01 PM | 🔵 | Identified hard-coded localhost in claude-md-utils.ts line 260 | ~352 |
| #37992 | 9:00 PM | 🔵 | Located claude-md-utils.ts for fixing hard-coded host | ~182 |
| #37979 | 8:33 PM | 🔴 | Fixed date parsing to use API date headers instead of "today" | ~315 |
| #37978 | " | 🔵 | Regenerated CLAUDE.md files across entire repository | ~268 |
| #37971 | 8:32 PM | 🔴 | Fixed Date Parsing in CLAUDE.md Generator to Use API Date Headers | ~388 |
| #37966 | 8:21 PM | 🔵 | Date Parsing Bug Located in claude-md-utils.ts | ~383 |
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38082 | 10:13 PM | ✅ | Merge Conflict Resolution - Kept Feature Branch Versions | ~431 |
| #37976 | 8:33 PM | 🔵 | CLAUDE.md shows recent entries with correct January 2026 dates | ~287 |
**worktree.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38076 | 9:53 PM | 🟣 | Worktree-Aware Project Filtering for Unified Timeline Context | ~578 |
**logger.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38048 | 9:45 PM | 🔴 | PR #558 - Comprehensive Bug Fix and Test Quality Improvement | ~585 |
| #37890 | 7:32 PM | ✅ | Committed DEFAULT_DATA_DIR Cross-Reference Documentation | ~326 |
| #37888 | " | ✅ | Logger DEFAULT_DATA_DIR Comment Updated to Cross-Reference SettingsDefaultsManager | ~311 |
| #37887 | " | ✅ | Added Cross-Reference Comment for DEFAULT_DATA_DIR Constant | ~361 |
| #37885 | " | ✅ | Added Cross-Reference Comment to Prevent DEFAULT_DATA_DIR Drift | ~344 |
| #37880 | 7:31 PM | 🔵 | Logger Implementation Uses Inline DEFAULT_DATA_DIR to Avoid Circular Dependency | ~354 |
| #37808 | 6:43 PM | 🔵 | Logger Module Only References SettingsDefaultsManager in Comments | ~357 |
| #37804 | 6:42 PM | 🔴 | Added readFileSync Import to Logger Module | ~257 |
| #37803 | " | 🔴 | Eliminated SettingsDefaultsManager Dependency from Logger Completely | ~375 |
| #37791 | 6:39 PM | 🔵 | Logger Module Exports formatTool Correctly in Direct Import | ~318 |
| #37781 | 6:36 PM | 🔴 | Added Lazy Log File Initialization to Logger Log Method | ~291 |
| #37780 | " | 🔴 | Fixed Circular Dependency Between Logger and SettingsDefaultsManager | ~426 |
| #37779 | " | 🔵 | SettingsDefaultsManager Uses Logger Methods | ~375 |
| #37778 | " | 🔵 | Logger Module Implementation Has formatTool Method | ~393 |
| #37774 | 6:35 PM | 🔵 | Circular Dependency Between Logger and SettingsDefaultsManager | ~326 |
| #37689 | 5:55 PM | 🔵 | Logger constructor immediately calls initializeLogFile which accesses SettingsDefaultsManager | ~409 |
| #37645 | 5:49 PM | 🔵 | Logger imports SettingsDefaultsManager for data directory and log level configuration | ~449 |
| #37642 | 5:41 PM | 🟣 | Second Task Agent Independently Created and Verified FormatTool Tests | ~544 |
| #37628 | 5:36 PM | 🔴 | Test Execution Shows Logger Circular Dependency Error | ~596 |
| #37627 | 5:35 PM | 🔵 | FormatTool Function Implementation and Fix Details | ~600 |
| #37626 | " | 🔵 | FormatTool Function Usage Across Codebase | ~493 |
| #37617 | 5:32 PM | ⚖️ | PR #558 Review Requirements Categorized by Priority | ~637 |
| #37613 | 5:31 PM | 🔵 | PR #558 Review Feedback Analysis | ~544 |
| #37575 | 4:52 PM | 🔴 | Phase 1 Committed - formatTool JSON.parse Fix | ~364 |
**tag-stripping.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37758 | 6:25 PM | ⚖️ | Integration Test Design for Four Critical Testing Gaps | ~729 |
### Jan 6, 2026
**bun-path.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38104 | 12:14 AM | 🔵 | Windows Compatibility Issues Documented Across 56 Memory Entries | ~509 |
*No recent activity*
</claude-mem-context>

View File

@@ -16,6 +16,43 @@ import { getWorkerHost } from '../shared/worker-utils.js';
const SETTINGS_PATH = path.join(os.homedir(), '.claude-mem', 'settings.json');
/**
* Validate that a file path is safe for CLAUDE.md generation.
* Rejects tilde paths, URLs, command-like strings, and paths with invalid chars.
*
* @param filePath - The file path to validate
* @param projectRoot - Optional project root for boundary checking
* @returns true if path is valid for CLAUDE.md processing
*/
function isValidPathForClaudeMd(filePath: string, projectRoot?: string): boolean {
// Reject empty or whitespace-only
if (!filePath || !filePath.trim()) return false;
// Reject tilde paths (Node.js doesn't expand ~)
if (filePath.startsWith('~')) return false;
// Reject URLs
if (filePath.startsWith('http://') || filePath.startsWith('https://')) return false;
// Reject paths with spaces (likely command text or PR references)
if (filePath.includes(' ')) return false;
// Reject paths with # (GitHub issue/PR references)
if (filePath.includes('#')) return false;
// If projectRoot provided, ensure path stays within project boundaries
if (projectRoot) {
// For relative paths, resolve against projectRoot; for absolute paths, use directly
const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(projectRoot, filePath);
const normalizedRoot = path.resolve(projectRoot);
if (!resolved.startsWith(normalizedRoot + path.sep) && resolved !== normalizedRoot) {
return false;
}
}
return true;
}
/**
* Replace tagged content in existing file, preserving content outside tags.
*
@@ -231,6 +268,14 @@ export async function updateFolderClaudeMdFiles(
const folderPaths = new Set<string>();
for (const filePath of filePaths) {
if (!filePath || filePath === '') continue;
// VALIDATE PATH BEFORE PROCESSING
if (!isValidPathForClaudeMd(filePath, projectRoot)) {
logger.debug('FOLDER_INDEX', 'Skipping invalid file path', {
filePath,
reason: 'Failed path validation'
});
continue;
}
// Resolve relative paths to absolute using projectRoot
let absoluteFilePath = filePath;
if (projectRoot && !path.isAbsolute(filePath)) {
@@ -264,7 +309,7 @@ export async function updateFolderClaudeMdFiles(
);
if (!response.ok) {
logger.warn('FOLDER_INDEX', 'Failed to fetch timeline', { folderPath, status: response.status });
logger.error('FOLDER_INDEX', 'Failed to fetch timeline', { folderPath, status: response.status });
continue;
}
@@ -281,7 +326,7 @@ export async function updateFolderClaudeMdFiles(
} catch (error) {
// Fire-and-forget: log warning but don't fail
const err = error as Error;
logger.warn('FOLDER_INDEX', 'Failed to update CLAUDE.md', {
logger.error('FOLDER_INDEX', 'Failed to update CLAUDE.md', {
folderPath,
errorMessage: err.message,
errorStack: err.stack

View File

@@ -42,7 +42,7 @@ export function readCursorRegistry(registryFile: string): CursorProjectRegistry
if (!existsSync(registryFile)) return {};
return JSON.parse(readFileSync(registryFile, 'utf-8'));
} catch (error) {
logger.warn('CONFIG', 'Failed to read Cursor registry, using empty registry', {
logger.error('CONFIG', 'Failed to read Cursor registry, using empty registry', {
file: registryFile,
error: error instanceof Error ? error.message : String(error)
});
@@ -151,7 +151,7 @@ export function configureCursorMcp(mcpJsonPath: string, mcpServerScriptPath: str
config.mcpServers = {};
}
} catch (error) {
logger.warn('CONFIG', 'Failed to read MCP config, starting fresh', {
logger.error('CONFIG', 'Failed to read MCP config, starting fresh', {
file: mcpJsonPath,
error: error instanceof Error ? error.message : String(error)
});

View File

@@ -53,7 +53,7 @@ export class TranscriptParser {
// Log summary if there were parse errors
if (this.parseErrors.length > 0) {
logger.warn('PARSER', `Failed to parse ${this.parseErrors.length} lines`, {
logger.error('PARSER', `Failed to parse ${this.parseErrors.length} lines`, {
path: transcriptPath,
totalLines: lines.length,
errorCount: this.parseErrors.length

View File

@@ -3,131 +3,58 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Nov 10, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #6358 | 3:14 PM | 🔵 | SDK Agent Spatial Awareness Implementation | ~309 |
### Nov 21, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #13289 | 2:20 PM | 🟣 | Comprehensive Test Suite for Transcript Transformation | ~320 |
### Nov 23, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #14617 | 6:15 PM | 🟣 | Test Suite Successfully Passing - All 8 Tests Green | ~498 |
| #14615 | 6:14 PM | 🟣 | YAGNI-Focused Test Suite for Transcript Transformation | ~457 |
### Dec 5, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20732 | 9:07 PM | 🔵 | Smart Install Version Marker Tests for Upgrade Detection | ~452 |
| #20399 | 7:17 PM | 🔵 | Smart install tests validate version tracking with backward compatibility | ~311 |
| #20392 | 7:15 PM | 🔵 | Memory tag stripping tests validate dual-tag system for JSON context filtering | ~404 |
| #20391 | " | 🔵 | User prompt tag stripping tests validate privacy controls for memory exclusion | ~182 |
### Jan 3, 2026
**logger-coverage.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36642 | 10:56 PM | 🔵 | Logger Coverage Test Requirements Analysis | ~483 |
| #36641 | " | 🔵 | Logger Coverage Test Suite Enforces Logging Standards | ~433 |
| #36616 | 10:42 PM | 🔵 | Logger Coverage Test Implementation Examined | ~540 |
**gemini_agent.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36639 | 10:55 PM | 🔵 | GeminiAgent Test Suite Structure | ~428 |
| #36637 | 10:47 PM | 🟣 | GeminiAgent Analysis Agent Running But Timed Out After 120 Seconds | ~521 |
| #36617 | 10:42 PM | 🔵 | GeminiAgent Test File Reveals Integration Requirements | ~506 |
**session_id_refactor.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36636 | 10:46 PM | 🟣 | Session ID Refactor Analysis Agent Completed Comprehensive Report | ~637 |
| #36615 | 10:42 PM | 🔵 | Session ID Refactor Test File Defines Expected Behavior | ~522 |
**session_store.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36635 | 10:46 PM | 🟣 | SessionStore Analysis Agent Completed Report Generation | ~545 |
| #36618 | 10:43 PM | 🔵 | SessionStore Test File Specifies Timestamp Override Feature | ~458 |
| #36485 | 9:12 PM | 🟣 | Prompts Module Test Suite Implemented | ~680 |
**session_id_usage_validation.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36625 | 10:44 PM | 🔵 | Documentation and Code Reveal Placeholder Detection Pattern | ~583 |
| #36619 | 10:43 PM | 🔵 | Session ID Validation Test Architecture Examined | ~705 |
**worker-spawn.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36570 | 9:54 PM | 🟣 | ProcessManager Infrastructure Test Suite Created | ~535 |
| #36663 | 11:06 PM | | Third Validation Test Updated: Resume Safety Check Now Uses NULL Comparison | ~417 |
| #36662 | " | | Second Validation Test Updated: Post-Capture Check Now Uses NULL Comparison | ~418 |
| #36661 | 11:05 PM | | First Validation Test Updated: Placeholder Detection Now Checks for NULL | ~482 |
| #36660 | " | ✅ | Updated Session ID Usage Validation Test Header to Reflect NULL-Based Architecture | ~588 |
| #36659 | " | ✅ | Sixth Test Fix: Updated Multi-Observation Test to Use Memory Session ID | ~486 |
| #36658 | " | | Fifth Test Fix: Updated storeSummary Tests to Use Actual Memory Session ID After Capture | ~555 |
| #36657 | 11:04 PM | ✅ | Fourth Test Fix: Updated storeObservation Tests to Use Actual Memory Session ID After Capture | ~547 |
| #36656 | " | | Third Test Fix: Updated getSessionById Test to Expect NULL for Uncaptured Memory Session ID | ~436 |
| #36655 | " | | Second Test Fix: Updated updateMemorySessionId Test to Expect NULL Before Update | ~395 |
| #36654 | " | | First Test Fix: Updated Memory Session ID Initialization Test to Expect NULL | ~426 |
| #36650 | 11:02 PM | 🔵 | Phase 1 Analysis Reveals Implementation-Test Mismatch on NULL vs Placeholder Initialization | ~687 |
| #36648 | " | 🔵 | Session ID Refactor Test Suite Documents Database Migration 17 and Dual ID System | ~651 |
| #36647 | 11:01 PM | 🔵 | SessionStore Test Suite Validates Prompt Counting and Timestamp Override Features | ~506 |
| #36646 | " | 🔵 | Session ID Architecture Revealed Through Test File Analysis | ~611 |
### Jan 4, 2026
**gemini_agent.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36908 | 2:01 AM | | Regression Tests Committed Successfully | ~418 |
| #36907 | " | | Regression Test Files Staged for Commit | ~317 |
| #36842 | 1:43 AM | 🔵 | Complete Test Framework and Pattern Documentation | ~670 |
| #36836 | 1:42 AM | 🔵 | GeminiAgent Test Coverage and Mocking Patterns | ~513 |
| #36751 | 12:32 AM | 🔵 | Gemini-Related Files Located Across Project | ~242 |
**session_store.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36840 | 1:43 AM | 🔵 | SessionStore Integration Test Pattern | ~444 |
### Jan 5, 2026
**sdk-agent-resume.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38086 | 10:42 PM | ✅ | Merged PR with comprehensive CLAUDE.md documentation system | ~478 |
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38082 | 10:13 PM | ✅ | Merge Conflict Resolution - Kept Feature Branch Versions | ~431 |
**gemini_agent.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37819 | 6:44 PM | 🔄 | Replaced Module Mock with SpyOn Approach for SettingsDefaultsManager | ~354 |
| #37816 | " | 🔄 | Removed Module-Level Mocks from Gemini Test | ~347 |
| #37815 | " | 🔵 | Gemini Test Has Two Module-Level Mocks Defined Before Describe Block | ~375 |
| #37814 | " | 🔵 | Gemini Test Uses mock.restore() in afterEach Hook | ~319 |
| #37811 | 6:43 PM | 🔵 | SettingsDefaultsManager Tests Still Fail With Gemini Test Due to Mock | ~384 |
| #37809 | " | 🔴 | Logger Tests Now Pass When Run With Gemini Test | ~340 |
| #37800 | 6:41 PM | 🔴 | Fixed Incomplete SettingsDefaultsManager Mock in Gemini Agent Test | ~376 |
| #37799 | " | 🔵 | Gemini Test Uses mock.module to Override SettingsDefaultsManager | ~357 |
| #37798 | " | 🔵 | Gemini Agent Test Identified as Source of Module Corruption | ~351 |
**logger-coverage.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37797 | 6:41 PM | 🔴 | Logger Coverage Test Now Passes With Other Tests After Exclusion | ~311 |
| #37793 | 6:39 PM | 🔴 | Added SettingsDefaultsManager to Logger Coverage Test Exclusions | ~355 |
| #37792 | " | 🔴 | Logger Tests Pass When Run Together With Coverage Test | ~345 |
| #37790 | " | 🔵 | Logger Coverage Test Detects Console Usage in SettingsDefaultsManager | ~391 |
| #37755 | 6:22 PM | 🔵 | Score 3 Marginal Tests Verified: Mock-Heavy Tests Validate Structure, Not Behavior | ~580 |
| #37750 | 6:21 PM | 🔵 | Test Audit: logger-coverage.test.ts Enforces Logging Standards Across Codebase | ~629 |
| #37735 | 6:16 PM | ✅ | Test Suite Audit Report Generated: 41 Tests Scored and Analyzed | ~634 |
| #37629 | 5:36 PM | 🔵 | Comprehensive Testing Patterns Documentation Generated | ~629 |
| #37620 | 5:33 PM | 🔵 | Existing Logger Coverage Test Suite Structure | ~536 |
| #37617 | 5:32 PM | ⚖️ | PR #558 Review Requirements Categorized by Priority | ~637 |
**session_id_refactor.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37777 | 6:36 PM | 🔴 | Phase 1 Test Cleanup Completed - 6 Low-Quality Test Files Deleted | ~430 |
| #37764 | 6:32 PM | ✅ | Deleted 6 harmful test files causing mock pollution and testing zero runtime value | ~454 |
| #37756 | 6:22 PM | ⚖️ | Score 2 Weak Tests Verification Confirms Audit Findings | ~598 |
**cursor-hook-outputs.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37758 | 6:25 PM | ⚖️ | Integration Test Design for Four Critical Testing Gaps | ~729 |
**session_id_usage_validation.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37754 | 6:22 PM | 🔵 | Test Audit: session_id_usage_validation.test.ts Enforces Critical Session ID Architecture Invariants | ~826 |
**worker-spawn.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37752 | 6:21 PM | 🔵 | Test Audit: worker-spawn.test.ts Tests Configuration and Contracts Without Testing Actual Spawning | ~651 |
**cursor-context-update.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37706 | 6:10 PM | 🔵 | Test Audit: cursor-context-update.test.ts Validates Cursor Integration File Format | ~468 |
**validate_sql_update.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37705 | 6:10 PM | 🔵 | Test Audit: validate_sql_update.test.ts Validates SQL Refactor Correctness | ~374 |
| #36858 | 1:50 AM | 🟣 | Phase 1 Implementation Completed via Subagent | ~499 |
| #36854 | 1:49 AM | 🟣 | gemini-3-flash Model Tests Added to GeminiAgent Test Suite | ~470 |
| #36851 | " | 🔵 | GeminiAgent Test Structure Analyzed | ~565 |
</claude-mem-context>

View File

@@ -58,8 +58,8 @@ describe('hook-constants', () => {
expect(HOOK_EXIT_CODES.FAILURE).toBe(1);
});
it('should define USER_MESSAGE_ONLY exit code', () => {
expect(HOOK_EXIT_CODES.USER_MESSAGE_ONLY).toBe(3);
it('should define BLOCKING_ERROR exit code', () => {
expect(HOOK_EXIT_CODES.BLOCKING_ERROR).toBe(2);
});
});

View File

@@ -3,51 +3,13 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**graceful-shutdown.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36574 | 9:55 PM | 🟣 | Phase 5 Infrastructure Tests Committed | ~357 |
| #36569 | 9:54 PM | 🟣 | GracefulShutdown Test Suite Created | ~457 |
**process-manager.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36571 | 9:54 PM | 🟣 | Phase 5 Infrastructure Tests Completed | ~504 |
| #36570 | " | 🟣 | ProcessManager Infrastructure Test Suite Created | ~535 |
**health-monitor.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36568 | 9:53 PM | 🟣 | HealthMonitor Test Suite Created for Phase 5 | ~437 |
### Jan 4, 2026
**wmic-parsing.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36924 | 2:25 AM | | Merged fix/pr-538-followups branch into main with comprehensive updates | ~481 |
| #36908 | 2:01 AM | | Regression Tests Committed Successfully | ~418 |
| #36907 | " | ✅ | Regression Test Files Staged for Commit | ~317 |
**process-manager.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36842 | 1:43 AM | 🔵 | Complete Test Framework and Pattern Documentation | ~670 |
| #36837 | 1:42 AM | 🔵 | ProcessManager Test Patterns with File System Operations | ~466 |
| #36779 | 12:44 AM | 🔵 | ProcessManager Windows PowerShell Functions Complete Analysis | ~550 |
### Jan 5, 2026
**wmic-parsing.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37735 | 6:16 PM | ✅ | Test Suite Audit Report Generated: 41 Tests Scored and Analyzed | ~634 |
**process-manager.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37629 | 5:36 PM | 🔵 | Comprehensive Testing Patterns Documentation Generated | ~629 |
| #37622 | 5:34 PM | 🔵 | Bun Test Pattern for File I/O and State Management | ~571 |
| #36870 | 1:54 AM | 🟣 | Phase 2 Implementation Completed via Subagent | ~572 |
| #36866 | 1:53 AM | 🔄 | WMIC Test Refactored to Use Direct Logic Testing | ~533 |
| #36865 | 1:52 AM | ✅ | WMIC Test File Updated with Improved Mock Implementation | ~370 |
| #36863 | 1:51 AM | 🟣 | WMIC Parsing Test File Created | ~581 |
| #36861 | " | 🔵 | Existing ProcessManager Test File Structure Analyzed | ~516 |
</claude-mem-context>

View File

@@ -0,0 +1,309 @@
/**
* Log Level Audit Test
*
* This test scans all TypeScript files in src/ to find logger calls,
* extracts the message text, and groups them by log level for review.
*
* Purpose: Help identify misclassified log messages that should be at a different level.
*
* Log Level Guidelines:
* - ERROR/failure: Critical failures that require investigation (data loss, service down)
* - WARN: Non-critical issues with fallback behavior (degraded, but functional)
* - INFO: Normal operational events (session started, request processed)
* - DEBUG: Detailed diagnostic information (variable values, flow tracing)
*/
import { describe, it, expect } from 'bun:test';
import { readdir, readFile } from 'fs/promises';
import { join, relative } from 'path';
const PROJECT_ROOT = join(import.meta.dir, '..');
const SRC_DIR = join(PROJECT_ROOT, 'src');
interface LoggerCall {
file: string;
line: number;
level: string;
component: string;
message: string;
errorParam: string | null;
fullMatch: string;
}
/**
* Recursively find all TypeScript files in a directory
*/
async function findTypeScriptFiles(dir: string): Promise<string[]> {
const files: string[] = [];
const entries = await readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...(await findTypeScriptFiles(fullPath)));
} else if (entry.isFile() && /\.ts$/.test(entry.name) && !/\.d\.ts$/.test(entry.name)) {
files.push(fullPath);
}
}
return files;
}
/**
* Extract logger calls from file content
* Handles multiline calls and captures error parameter (4th arg)
*/
function extractLoggerCalls(content: string, filePath: string): LoggerCall[] {
const calls: LoggerCall[] = [];
const lines = content.split('\n');
const seenCalls = new Set<string>();
// Build line number index for position-to-line lookup
const lineStarts: number[] = [0];
for (let i = 0; i < content.length; i++) {
if (content[i] === '\n') {
lineStarts.push(i + 1);
}
}
function getLineNumber(pos: number): number {
for (let i = lineStarts.length - 1; i >= 0; i--) {
if (lineStarts[i] <= pos) return i + 1;
}
return 1;
}
// Pattern that matches logger calls across multiple lines
// Captures: method, component, message, and everything up to closing paren
// Uses [\s\S] instead of . to match newlines
const loggerPattern = /logger\.(error|warn|info|debug|failure|success|timing|dataIn|dataOut|happyPathError)\s*\(\s*['"]([^'"]+)['"][\s\S]*?\)/g;
let match: RegExpExecArray | null;
while ((match = loggerPattern.exec(content)) !== null) {
const fullMatch = match[0];
const method = match[1];
const component = match[2];
const lineNum = getLineNumber(match.index);
// Extract message (2nd string arg) - could be single, double, or template
const messageMatch = fullMatch.match(/['"][^'"]+['"]\s*,\s*(['"`])([\s\S]*?)\1/);
const message = messageMatch ? messageMatch[2] : '(message not captured)';
// Extract error parameter (4th arg) - look for "error as Error" or similar patterns
let errorParam: string | null = null;
const errorMatch = fullMatch.match(/,\s*(error|err|e)\s+as\s+Error\s*\)/i) ||
fullMatch.match(/,\s*(error|err|e)\s*\)/i) ||
fullMatch.match(/,\s*new\s+Error\s*\([^)]*\)\s*\)/i);
if (errorMatch) {
errorParam = errorMatch[0].replace(/^\s*,\s*/, '').replace(/\s*\)\s*$/, '');
}
const key = `${filePath}:${lineNum}:${method}:${message.substring(0, 50)}`;
if (!seenCalls.has(key)) {
seenCalls.add(key);
calls.push({
file: relative(PROJECT_ROOT, filePath),
line: lineNum,
level: normalizeLevel(method),
component,
message,
errorParam,
fullMatch: fullMatch.replace(/\s+/g, ' ').trim() // Normalize whitespace for display
});
}
}
return calls;
}
/**
* Normalize log level names to standard categories
*/
function normalizeLevel(method: string): string {
switch (method) {
case 'error':
case 'failure':
return 'ERROR';
case 'warn':
case 'happyPathError':
return 'WARN';
case 'info':
case 'success':
case 'timing':
case 'dataIn':
case 'dataOut':
return 'INFO';
case 'debug':
return 'DEBUG';
default:
return method.toUpperCase();
}
}
/**
* Generate formatted audit report
*/
function generateReport(calls: LoggerCall[]): string {
const byLevel: Record<string, LoggerCall[]> = {
'ERROR': [],
'WARN': [],
'INFO': [],
'DEBUG': []
};
for (const call of calls) {
if (byLevel[call.level]) {
byLevel[call.level].push(call);
}
}
const lines: string[] = [];
lines.push('\n=== LOG LEVEL AUDIT REPORT ===\n');
lines.push(`Total logger calls found: ${calls.length}\n`);
// ERROR level
lines.push('');
lines.push('ERROR (should be critical failures only):');
lines.push('─'.repeat(60));
if (byLevel['ERROR'].length === 0) {
lines.push(' (none found)');
} else {
for (const call of byLevel['ERROR'].sort((a, b) => a.file.localeCompare(b.file))) {
lines.push(` ${call.file}:${call.line} [${call.component}]`);
lines.push(` message: "${formatMessage(call.message)}"`);
if (call.errorParam) {
lines.push(` error: ${call.errorParam}`);
}
lines.push(` full: ${call.fullMatch}`);
lines.push('');
}
}
lines.push(` Count: ${byLevel['ERROR'].length}`);
// WARN level
lines.push('');
lines.push('WARN (should be non-critical, has fallback):');
lines.push('─'.repeat(60));
if (byLevel['WARN'].length === 0) {
lines.push(' (none found)');
} else {
for (const call of byLevel['WARN'].sort((a, b) => a.file.localeCompare(b.file))) {
lines.push(` ${call.file}:${call.line} [${call.component}]`);
lines.push(` message: "${formatMessage(call.message)}"`);
if (call.errorParam) {
lines.push(` error: ${call.errorParam}`);
}
lines.push(` full: ${call.fullMatch}`);
lines.push('');
}
}
lines.push(` Count: ${byLevel['WARN'].length}`);
// INFO level
lines.push('');
lines.push('INFO (informational):');
lines.push('─'.repeat(60));
if (byLevel['INFO'].length === 0) {
lines.push(' (none found)');
} else {
for (const call of byLevel['INFO'].sort((a, b) => a.file.localeCompare(b.file))) {
lines.push(` ${call.file}:${call.line} [${call.component}]`);
lines.push(` message: "${formatMessage(call.message)}"`);
if (call.errorParam) {
lines.push(` error: ${call.errorParam}`);
}
lines.push(` full: ${call.fullMatch}`);
lines.push('');
}
}
lines.push(` Count: ${byLevel['INFO'].length}`);
// DEBUG level
lines.push('');
lines.push('DEBUG (detailed diagnostics):');
lines.push('─'.repeat(60));
if (byLevel['DEBUG'].length === 0) {
lines.push(' (none found)');
} else {
for (const call of byLevel['DEBUG'].sort((a, b) => a.file.localeCompare(b.file))) {
lines.push(` ${call.file}:${call.line} [${call.component}]`);
lines.push(` message: "${formatMessage(call.message)}"`);
if (call.errorParam) {
lines.push(` error: ${call.errorParam}`);
}
lines.push(` full: ${call.fullMatch}`);
lines.push('');
}
}
lines.push(` Count: ${byLevel['DEBUG'].length}`);
// Summary
lines.push('');
lines.push('=== SUMMARY ===');
lines.push(` ERROR: ${byLevel['ERROR'].length}`);
lines.push(` WARN: ${byLevel['WARN'].length}`);
lines.push(` INFO: ${byLevel['INFO'].length}`);
lines.push(` DEBUG: ${byLevel['DEBUG'].length}`);
lines.push(` TOTAL: ${calls.length}`);
lines.push('');
return lines.join('\n');
}
/**
* Format message for display - NO TRUNCATION
*/
function formatMessage(message: string): string {
return message;
}
describe('Log Level Audit', () => {
let allCalls: LoggerCall[] = [];
it('should scan all TypeScript files and extract logger calls', async () => {
const files = await findTypeScriptFiles(SRC_DIR);
expect(files.length).toBeGreaterThan(0);
for (const file of files) {
const content = await readFile(file, 'utf-8');
const calls = extractLoggerCalls(content, file);
allCalls.push(...calls);
}
expect(allCalls.length).toBeGreaterThan(0);
});
it('should generate audit report for log level review', () => {
const report = generateReport(allCalls);
console.log(report);
// This test always passes - it's for generating a review report
expect(true).toBe(true);
});
it('should have summary statistics', () => {
const byLevel: Record<string, number> = {
'ERROR': 0,
'WARN': 0,
'INFO': 0,
'DEBUG': 0
};
for (const call of allCalls) {
if (byLevel[call.level] !== undefined) {
byLevel[call.level]++;
}
}
console.log('\n📊 Log Level Distribution:');
console.log(` ERROR: ${byLevel['ERROR']} (${((byLevel['ERROR'] / allCalls.length) * 100).toFixed(1)}%)`);
console.log(` WARN: ${byLevel['WARN']} (${((byLevel['WARN'] / allCalls.length) * 100).toFixed(1)}%)`);
console.log(` INFO: ${byLevel['INFO']} (${((byLevel['INFO'] / allCalls.length) * 100).toFixed(1)}%)`);
console.log(` DEBUG: ${byLevel['DEBUG']} (${((byLevel['DEBUG'] / allCalls.length) * 100).toFixed(1)}%)`);
// Log distribution health check - not a hard failure, just informational
// A healthy codebase typically has: DEBUG > INFO > WARN > ERROR
expect(allCalls.length).toBeGreaterThan(0);
});
});

View File

@@ -34,6 +34,7 @@ const EXCLUDED_PATTERNS = [
/worker-service\.ts$/, // CLI entry point with interactive setup wizard (console.log for user prompts)
/integrations\/.*Installer\.ts$/, // CLI installer commands (console.log for interactive installation output)
/SettingsDefaultsManager\.ts$/, // Must use console.log to avoid circular dependency with logger
/user-message-hook\.ts$/, // Deprecated - kept for reference only, not registered in hooks.json
];
// Files that should always use logger (core business logic)

View File

@@ -3,36 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 5, 2026
**claude-md-utils.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38086 | 10:42 PM | ✅ | Merged PR with comprehensive CLAUDE.md documentation system | ~478 |
| #38047 | 9:45 PM | 🔴 | PR #556 Review Items - Worker Host Configuration and Path Resolution | ~389 |
| #38025 | 9:15 PM | 🔴 | Fixed PR #556 review items and committed changes | ~344 |
| #38024 | " | ✅ | Git status shows modified source files and auto-updated CLAUDE.md files | ~295 |
| #38022 | " | ✅ | Phase 3 complete: Worktree detection test coverage verified by agent | ~391 |
| #38021 | " | 🔵 | Test suite expanded with additional projectRoot edge case tests | ~389 |
| #38020 | 9:14 PM | ✅ | All 27 tests passing in claude-md-utils test suite | ~237 |
| #38019 | " | ✅ | Test suite passed for claude-md-utils.ts with all 27 tests green | ~306 |
| #38018 | " | 🟣 | Added comprehensive test coverage for worktree detection and projectRoot path resolution | ~450 |
| #38017 | " | ✅ | Verified existing claude-md-utils.test.ts passes with 27 tests | ~244 |
| #38016 | 9:13 PM | 🔵 | Existing test suite for claude-md-utils.ts with projectRoot tests already present | ~426 |
| #37977 | 8:33 PM | 🔵 | All 23 tests pass for claude-md-utils module | ~209 |
**logger-format-tool.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37809 | 6:43 PM | 🔴 | Logger Tests Now Pass When Run With Gemini Test | ~340 |
| #37797 | 6:41 PM | 🔴 | Logger Coverage Test Now Passes With Other Tests After Exclusion | ~311 |
| #37796 | 6:40 PM | 🔴 | Utils and Shared Tests Pass When Run Together | ~342 |
| #37792 | 6:39 PM | 🔴 | Logger Tests Pass When Run Together With Coverage Test | ~345 |
| #37789 | 6:38 PM | 🔴 | Logger FormatTool Tests Pass When Run In Isolation | ~359 |
| #37777 | 6:36 PM | 🔴 | Phase 1 Test Cleanup Completed - 6 Low-Quality Test Files Deleted | ~430 |
| #37769 | 6:34 PM | 🔵 | Logger-format-tool test file contains 81 comprehensive tests for non-existent logger.formatTool method | ~487 |
| #37655 | 5:51 PM | 🔵 | Logger formatTool test imports logger directly creating test-time circular dependency exposure | ~392 |
| #37642 | 5:41 PM | 🟣 | Second Task Agent Independently Created and Verified FormatTool Tests | ~544 |
| #37638 | 5:40 PM | 🟣 | FormatTool Test Suite Successfully Passes All 56 Tests | ~515 |
| #37635 | 5:39 PM | 🟣 | Created Comprehensive FormatTool Test Suite | ~619 |
*No recent activity*
</claude-mem-context>

View File

@@ -1,6 +1,6 @@
import { describe, it, expect, mock, afterEach, beforeEach } from 'bun:test';
import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'fs';
import { join } from 'path';
import path, { join } from 'path';
import { tmpdir } from 'os';
// Mock logger BEFORE imports (required pattern)
@@ -322,7 +322,7 @@ describe('updateFolderClaudeMdFiles', () => {
expect(callUrl).toContain(encodeURIComponent('/home/user/my-project/src/utils'));
});
it('should not modify absolute paths even with projectRoot', async () => {
it('should accept absolute paths within projectRoot and use them directly', async () => {
const folderPath = join(tempDir, 'absolute-path-test');
const filePath = join(folderPath, 'file.ts');
@@ -339,10 +339,10 @@ describe('updateFolderClaudeMdFiles', () => {
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
[filePath], // absolute path
[filePath], // absolute path within tempDir
'test-project',
37777,
'/home/user/my-project' // projectRoot should be ignored
tempDir // projectRoot matches the absolute path's root
);
// Should call API with the original absolute path's folder
@@ -485,3 +485,152 @@ describe('updateFolderClaudeMdFiles', () => {
expect(callUrl).toContain(encodeURIComponent('/home/user/project/src'));
});
});
describe('path validation in updateFolderClaudeMdFiles', () => {
it('should reject tilde paths', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['~/.claude-mem/logs/worker.log'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject URLs', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['https://example.com/file.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject paths with spaces', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['PR #610 on thedotmack/CLAUDE.md'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject paths with hash symbols', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['issue#123/file.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject path traversal outside project', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['../../../etc/passwd'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should reject absolute paths outside project root', async () => {
const fetchMock = mock(() => Promise.resolve({ ok: true } as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['/etc/passwd'],
'test-project',
37777,
tempDir
);
expect(fetchMock).not.toHaveBeenCalled();
});
it('should accept absolute paths within project root', async () => {
const apiResponse = {
content: [{ text: '| #123 | 4:30 PM | 🔵 | Test | ~100 |' }]
};
const fetchMock = mock(() => Promise.resolve({
ok: true,
json: () => Promise.resolve(apiResponse)
} as Response));
global.fetch = fetchMock;
// Create an absolute path within the temp directory
const absolutePathInProject = path.join(tempDir, 'src', 'utils', 'file.ts');
await updateFolderClaudeMdFiles(
[absolutePathInProject],
'test-project',
37777,
tempDir
);
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it('should accept absolute paths when no projectRoot is provided', async () => {
const apiResponse = {
content: [{ text: '| #123 | 4:30 PM | 🔵 | Test | ~100 |' }]
};
const fetchMock = mock(() => Promise.resolve({
ok: true,
json: () => Promise.resolve(apiResponse)
} as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['/home/user/valid/file.ts'],
'test-project',
37777
// No projectRoot provided
);
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it('should accept valid relative paths', async () => {
const apiResponse = {
content: [{ text: '| #123 | 4:30 PM | 🔵 | Test | ~100 |' }]
};
const fetchMock = mock(() => Promise.resolve({
ok: true,
json: () => Promise.resolve(apiResponse)
} as Response));
global.fetch = fetchMock;
await updateFolderClaudeMdFiles(
['src/utils/logger.ts'],
'test-project',
37777,
tempDir
);
expect(fetchMock).toHaveBeenCalledTimes(1);
});
});

View File

@@ -3,49 +3,5 @@
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 3, 2026
**fallback-error-handler.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36522 | 9:34 PM | 🟣 | Phase 2 Worker Agent Tests Implemented | ~390 |
| #36525 | " | 🔵 | Test Import Strategy for Avoiding Module Side Effects | ~358 |
| #36518 | " | 🟣 | Phase 2 Test Suite Implementation Complete | ~348 |
| #36521 | " | ⚖️ | Test Import Strategy: Direct Imports Over Barrel Exports | ~321 |
| #36515 | 9:33 PM | 🟣 | Phase 2 Worker Agents Test Suite Implementation | ~422 |
### Jan 4, 2026
**observation-broadcaster.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36842 | 1:43 AM | 🔵 | Complete Test Framework and Pattern Documentation | ~670 |
| #36834 | 1:41 AM | 🔵 | Bun Test Framework Pattern and Structure | ~418 |
### Jan 5, 2026
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38078 | 9:54 PM | ✅ | CLAUDE.md Documentation Cleanup - 1,233 Lines Removed Across 18 Files | ~590 |
**response-processor.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37999 | 9:02 PM | 🔵 | getWorkerHost and getWorkerPort used in 18 files across codebase | ~282 |
| #37756 | 6:22 PM | ⚖️ | Score 2 Weak Tests Verification Confirms Audit Findings | ~598 |
| #37712 | 6:12 PM | 🔵 | Test Audit: response-processor.test.ts Has Heavy Mocking for XML Parsing and Database Operations | ~697 |
**observation-broadcaster.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37777 | 6:36 PM | 🔴 | Phase 1 Test Cleanup Completed - 6 Low-Quality Test Files Deleted | ~430 |
| #37764 | 6:32 PM | ✅ | Deleted 6 harmful test files causing mock pollution and testing zero runtime value | ~454 |
| #37755 | 6:22 PM | 🔵 | Score 3 Marginal Tests Verified: Mock-Heavy Tests Validate Structure, Not Behavior | ~580 |
| #37711 | 6:11 PM | 🔵 | Test Audit: observation-broadcaster.test.ts Validates SSE Broadcasting with Mock Workers | ~605 |
**fallback-error-handler.test.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #37735 | 6:16 PM | ✅ | Test Suite Audit Report Generated: 41 Tests Scored and Analyzed | ~634 |
*No recent activity*
</claude-mem-context>

View File

@@ -1,26 +0,0 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 3, 2025
**settings.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #19956 | 10:13 PM | 🔵 | No MCP Servers Currently Configured | ~230 |
### Dec 5, 2025
**settings.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20295 | 6:07 PM | 🔵 | Claude Settings Configuration with Plugin Enablement | ~319 |
### Dec 31, 2025
**settings.json**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34618 | 2:59 PM | 🔵 | Make-Plan and Do Skills Already Configured in Claude Settings | ~373 |
</claude-mem-context>

View File

@@ -1,157 +0,0 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Nov 30, 2025
**hidden-sniffing-nest.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #17674 | 6:01 PM | ⚖️ | Plan Mode Exited with Finalized Dual-Tag Implementation Strategy | ~692 |
| #17669 | 5:55 PM | ⚖️ | Implementation Plan Updated with User Requirements Clarification | ~735 |
| #17646 | 5:42 PM | ⚖️ | Implementation Plan Created for Dual-Tag System Feature Extraction | ~625 |
### Dec 5, 2025
**distributed-growing-wall-agent-648df112.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20982 | 11:47 PM | 🔵 | Implementation Plan Retrieved: Nine-Phase Selective Hook Refactoring Strategy | ~487 |
| #20373 | 7:00 PM | ⚖️ | Implementation plan created for selective merge of hook refactoring | ~367 |
**distributed-growing-wall.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20375 | 7:02 PM | ✅ | Simplified implementation plan created for primary session | ~346 |
### Dec 7, 2025
**staged-whistling-ember.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #21295 | 6:28 PM | ⚖️ | Phase 2 MCP DRY Architecture Plan Created | ~586 |
### Dec 9, 2025
**fancy-purring-horizon.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23061 | 6:17 PM | 🔵 | Claude-Mem Hooks Cleanup Plan Structure Reviewed | ~400 |
### Dec 10, 2025
**abundant-purring-crystal.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23712 | 8:56 PM | ⚖️ | PM2 Replacement Architecture: Bun-based Self-Executable Worker Service | ~825 |
### Dec 12, 2025
**abundant-purring-crystal.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24402 | 8:10 PM | 🔵 | Retrieved PM2 Replacement Architecture Decision from Memory | ~476 |
**concurrent-snuggling-goblet.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24284 | 5:31 PM | 🔵 | PM2 to Bun Migration Plan for Worker Process Management | ~414 |
| #24283 | 5:30 PM | ⚖️ | Six-phase implementation plan created to address PR #248 issues | ~652 |
| #24282 | 5:22 PM | ⚖️ | PR #248 review plan identifies six issues requiring fixes before merge | ~640 |
### Dec 13, 2025
**smooth-whistling-mccarthy.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #25444 | 10:02 PM | 🔵 | Error Message Quality Improvement Plan Loaded | ~371 |
### Dec 18, 2025
**indexed-jingling-pinwheel.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29414 | 4:06 PM | 🔵 | Mode-based prompt customization plan has critical scope gaps | ~465 |
### Dec 19, 2025
**precious-bubbling-ember.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30066 | 8:00 PM | 🔵 | RAGTIME Tool Blocking Prevents Observation Hook System | ~596 |
### Dec 20, 2025
**recursive-juggling-clover.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30974 | 7:12 PM | 🔵 | Nonsense Audit Plan Review - Final Issue Remaining | ~375 |
| #30962 | 7:08 PM | 🔴 | Expanded logger.formatTool() to Handle All Tool Types | ~425 |
| #30960 | 7:07 PM | 🔵 | Issue 18 of 20 Identified in Nonsense Audit Plan | ~317 |
| #30935 | 6:56 PM | 🔄 | Removed Ceremonial Wrapper Function in Hook Response System | ~382 |
| #30925 | 6:53 PM | 🔴 | Removed Redundant Try-Catch from getWorkerPort() | ~360 |
| #30916 | 6:49 PM | ✅ | Phase 2 Major Cleanup Milestone Completed | ~364 |
| #30915 | " | 🔴 | SessionRoutes Catch-All Exception Masking Removed | ~345 |
| #30909 | 6:48 PM | 🔵 | Loaded Comprehensive Code Quality Audit Plan | ~402 |
| #30888 | 6:40 PM | ✅ | Phase 2 Progress Updated | ~306 |
| #30887 | " | 🔄 | Tag-Stripping DRY Violation Fixed | ~417 |
| #30881 | 6:37 PM | 🔴 | Eliminated Triple-Duplicated Date/Time Formatting Functions | ~366 |
| #30880 | " | 🔵 | Issue 8: Duplicate Date/Time Formatting Functions in SearchManager | ~214 |
| #30862 | 6:26 PM | 🔴 | Cleanup Hook Error Logging Added | ~297 |
| #30853 | 6:20 PM | 🔴 | Summary Hook Finally Block Error Propagation Fixed | ~323 |
| #30849 | 6:19 PM | 🔵 | Nonsense Audit Plan Identified - Issue 5 Summary Hook Error Masking | ~408 |
| #30842 | 6:18 PM | ✅ | Phase 1 Critical Fixes Marked Complete | ~449 |
| #30841 | 6:17 PM | 🔵 | Code Quality Remediation Plan Structure | ~406 |
| #32289 | 6:09 PM | 🔴 | Vector Search Failures Now Show Explicit Error Messages | ~267 |
**delightful-gliding-hinton.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30519 | 4:48 PM | 🔵 | Plan file contains multi-phase deployment strategy | ~209 |
| #30514 | 4:46 PM | 🟣 | Sequential Phase Execution System for Plan Deployment | ~213 |
### Dec 28, 2025
**cozy-percolating-clover.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33567 | 11:06 PM | 🔴 | Validation of Memory Session Append Bug Fix | ~251 |
**mellow-discovering-meerkat.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33265 | 2:58 PM | 🟣 | Self-spawn pattern for background worker lifecycle management | ~446 |
| #33264 | " | 🟣 | Worker Lifecycle Management PR Created (PR #458) | ~432 |
### Dec 29, 2025
**sprightly-frolicking-tulip.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34215 | 10:08 PM | 🔵 | Retrieved Detailed Cursor Integration Implementation History | ~676 |
| #34124 | 9:09 PM | 🔵 | Cursor Hooks Integration Branch Code Review Completed | ~571 |
| #34098 | 9:03 PM | 🔵 | Cursor Hooks Integration Branch Code Review Completed | ~413 |
| #34087 | 9:00 PM | 🔵 | Comprehensive code review plan for Cursor IDE hooks integration | ~449 |
### Dec 30, 2025
**lively-twirling-garden.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34413 | 1:59 PM | 🔵 | Agent SDK V2 Upgrade Plan Reviewed | ~380 |
### Jan 4, 2026
**gentle-munching-wolf.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36729 | 12:23 AM | ⚖️ | Implementation Plan Created for PR Review Follow-ups and Issue Fixes | ~673 |
### Jan 5, 2026
**rustling-crunching-thimble.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #38007 | 9:04 PM | ⚖️ | Created implementation plan for three PR review items | ~373 |
</claude-mem-context>