feat: Live Context System with Distributed CLAUDE.md Generation (#556)

* docs: add folder index generator plan

RFC for auto-generating folder-level CLAUDE.md files with observation
timelines. Includes IDE symlink support and root CLAUDE.md integration.

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

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

* feat: implement folder index generator (Phase 1)

Add automatic CLAUDE.md generation for folders containing observed files.
This enables IDE context providers to access relevant memory observations.

Core modules:
- FolderDiscovery: Extract folders from observation file paths
- FolderTimelineCompiler: Compile chronological timeline per folder
- ClaudeMdGenerator: Write CLAUDE.md with tag-based content replacement
- FolderIndexOrchestrator: Coordinate regeneration on observation save

Integration:
- Event-driven regeneration after observation save in ResponseProcessor
- HTTP endpoints for folder discovery, timeline, and manual generation
- Settings for enabling/configuring folder index behavior

The <claude-mem-context> tag wrapping ensures:
- Manual CLAUDE.md content is preserved
- Auto-generated content won't be recursively observed
- Clean separation between user and system content

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

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

* feat: add updateFolderClaudeMd function to CursorHooksInstaller

Adds function to update CLAUDE.md files for folders touched by observations.
Uses existing /api/search/by-file endpoint, preserves content outside
<claude-mem-context> tags, and writes atomically via temp file + rename.

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

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

* feat: hook updateFolderClaudeMd into ResponseProcessor

Calls updateFolderClaudeMd after observation save to update folder-level
CLAUDE.md files. Uses fire-and-forget pattern with error logging.
Extracts file paths from saved observations and workspace path from registry.

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

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

* feat: add timeline formatting for folder CLAUDE.md files

Implements formatTimelineForClaudeMd function that transforms API response
into compact markdown table format. Converts emojis to text labels,
handles ditto marks for timestamps, and groups under "Recent" header.

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

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

* refactor: remove old folder-index implementation

Deletes redundant folder-index services that were replaced by the simpler
updateFolderClaudeMd approach in CursorHooksInstaller.ts.

Removed:
- src/services/folder-index/ directory (5 files)
- FolderIndexRoutes.ts
- folder-index settings from SettingsDefaultsManager
- folder-index route registration from worker-service

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

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

* feat: add worktree-aware project filtering for unified timelines

Detect git worktrees and show both parent repo and worktree observations
in the session start timeline. When running in a worktree, the context
now includes observations from both projects, interleaved chronologically.

- Add detectWorktree() utility to identify worktree directories
- Add getProjectContext() to return parent + worktree projects
- Update context hook to pass multi-project queries
- Add queryObservationsMulti() and querySummariesMulti() for IN clauses
- Maintain backward compatibility with single-project queries

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

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

* fix: restructure logging to prove session correctness and reduce noise

Add critical logging at each stage of the session lifecycle to prove the session ID chain (contentSessionId → sessionDbId → memorySessionId) stays aligned. New logs include CREATED, ENQUEUED, CLAIMED, MEMORY_ID_CAPTURED, STORING, and STORED. Move intermediate migration and backfill progress logs to DEBUG level to reduce noise, keeping only essential initialization and completion logs at INFO level.

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

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

* refactor: extract folder CLAUDE.md utils to shared location

Moves folder CLAUDE.md utilities from CursorHooksInstaller to a new
shared utils file. Removes Cursor registry dependency - file paths
from observations are already absolute, no workspace lookup needed.

New file: src/utils/claude-md-utils.ts
- replaceTaggedContent() - preserves user content outside tags
- writeClaudeMdToFolder() - atomic writes with tag preservation
- formatTimelineForClaudeMd() - API response to compact markdown
- updateFolderClaudeMdFiles() - orchestrates folder updates

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

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

* fix: trigger folder CLAUDE.md updates when observations are saved

The folder CLAUDE.md update was previously only triggered in
syncAndBroadcastSummary, but summaries run with observationCount=0
(observations are saved separately). Moved the update logic to
syncAndBroadcastObservations where file paths are available.

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

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

* all the claudes

* test: add unit tests for claude-md-utils pure functions

Add 11 tests covering replaceTaggedContent and formatTimelineForClaudeMd:
- replaceTaggedContent: empty content, tag replacement, appending, partial tags
- formatTimelineForClaudeMd: empty input, parsing, ditto marks, session IDs

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

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

* test: add integration tests for file operation functions

Add 9 tests for writeClaudeMdToFolder and updateFolderClaudeMdFiles:
- writeClaudeMdToFolder: folder creation, content preservation, nested dirs, atomic writes
- updateFolderClaudeMdFiles: empty skip, fetch/write, deduplication, error handling

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

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

* test: add unit tests for timeline-formatting utilities

Add 14 tests for extractFirstFile and groupByDate functions:
- extractFirstFile: relative paths, fallback to files_read, null handling, invalid JSON
- groupByDate: empty arrays, date grouping, chronological sorting, item preservation

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

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

* chore: rebuild plugin scripts with merged features

* docs: add project-specific CLAUDE.md with architecture and development notes

* fix: exclude project root from auto-generated CLAUDE.md updates

Skip folders containing .git directory when auto-updating subfolder
CLAUDE.md files. This ensures:

1. Root CLAUDE.md remains user-managed and untouched by the system
2. SessionStart context injection stays pristine throughout the session
3. Subfolder CLAUDE.md files continue to receive live context updates
4. Cleaner separation between user-authored root docs and auto-generated folder indexes

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

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

* fix: prevent crash from resuming stale SDK sessions on worker restart

When the worker restarts, it was incorrectly passing the `resume` parameter
to INIT prompts (lastPromptNumber=1) when a memorySessionId existed from a
previous SDK session. This caused "Claude Code process exited with code 1"
crashes because the SDK tried to resume into a session that no longer exists.

Root cause: The resume condition only checked `hasRealMemorySessionId` but
did not verify that this was a CONTINUATION prompt (lastPromptNumber > 1).

Fix: Add `session.lastPromptNumber > 1` check to the resume condition:
- Before: `...(hasRealMemorySessionId && { resume: session.memorySessionId })`
- After: `...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: ... })`

Also added:
- Enhanced debug logging that warns when skipping resume for INIT prompts
- Unit tests in tests/sdk-agent-resume.test.ts (9 test cases)

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

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

* fix: properly handle Chroma MCP connection errors

Previously, ensureCollection() caught ALL errors from chroma_get_collection_info
and assumed they meant "collection doesn't exist", triggering unnecessary
collection creation attempts. Connection errors like "Not connected" or
"MCP error -32000: Connection closed" would cascade into failed creation attempts.

Similarly, queryChroma() would silently return empty results when the MCP call
failed, masking the underlying connection problem.

Changes:
- ensureCollection(): Detect connection errors and re-throw immediately instead
  of attempting collection creation
- queryChroma(): Wrap MCP call in try-catch and throw connection errors instead
  of returning empty results
- Both methods reset connection state (connected=false, client=null) on
  connection errors so subsequent operations can attempt to reconnect

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

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

* pushed

* fix: scope regenerate-claude-md.ts to current working directory

Critical bug fix: The script was querying ALL observations from the database
across ALL projects ever recorded (1396+ folders), then attempting to write
CLAUDE.md files everywhere including other projects, non-existent paths, and
ignored directories.

Changes:
- Use git ls-files to discover folders (respects .gitignore automatically)
- Filter database query to current project only (by folder name)
- Use relative paths for database queries (matches storage format)
- Add --clean flag to remove auto-generated CLAUDE.md files
- Add fallback directory walker for non-git repos

Now correctly scopes to 26 folders with observations instead of 1396+.

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

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

* docs and adjustments

* fix: cleanup mode strips tags instead of deleting files blindly

The cleanup mode was incorrectly deleting entire files that contained
<claude-mem-context> tags. The correct behavior (per original design):

1. Strip the <claude-mem-context>...</claude-mem-context> section
2. If empty after stripping → delete the file
3. If has remaining content → save the stripped version

Now properly preserves user content in CLAUDE.md files while removing
only the auto-generated sections.

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

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

* deleted some files

* chore: regenerate folder CLAUDE.md files with fixed script

Regenerated 23 folder CLAUDE.md files using the corrected script that:
- Scopes to current working directory only
- Uses git ls-files to respect .gitignore
- Filters by project name

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

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

* Update CLAUDE.md files for January 5, 2026

- Regenerated and staged 23 CLAUDE.md files with a mix of new and modified content.
- Fixed cleanup mode to properly strip tags instead of deleting files blindly.
- Cleaned up empty CLAUDE.md files from various directories, including ~/.claude and ~/Scripts.
- Conducted dry-run cleanup that identified a significant reduction in auto-generated CLAUDE.md files.
- Removed the isAutoGeneratedClaudeMd function due to incorrect file deletion behavior.

* feat: use settings for observation limit in batch regeneration script

Replace hard-coded limit of 10 with configurable CLAUDE_MEM_CONTEXT_OBSERVATIONS
setting (default: 50). This allows users to control how many observations appear
in folder CLAUDE.md files.

Changes:
- Import SettingsDefaultsManager and load settings at script startup
- Use OBSERVATION_LIMIT constant derived from settings at both call sites
- Remove stale default parameter from findObservationsByFolder function

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

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

* feat: use settings for observation limit in event-driven updates

Replace hard-coded limit of 10 in updateFolderClaudeMdFiles with
configurable CLAUDE_MEM_CONTEXT_OBSERVATIONS setting (default: 50).

Changes:
- Import SettingsDefaultsManager and os module
- Load settings at function start (once, not in loop)
- Use limit from settings in API call

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

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

* feat: Implement configurable observation limits and enhance search functionality

- Added configurable observation limits to batch regeneration scripts.
- Enhanced SearchManager to handle folder queries and normalize parameters.
- Introduced methods to check for direct child files in observations and sessions.
- Updated SearchOptions interface to include isFolder flag for filtering.
- Improved code quality with comprehensive reviews and anti-pattern checks.
- Cleaned up auto-generated CLAUDE.md files across various directories.
- Documented recent changes and improvements in CLAUDE.md files.

* build asset

* Project Context from Claude-Mem auto-added (can be auto removed at any time)

* CLAUDE.md updates

* fix: resolve CLAUDE.md files to correct directory in worktree setups

When using git worktrees, CLAUDE.md files were being written relative to
the worker's process.cwd() instead of the actual project directory. This
fix threads the project's cwd from message processing through to the file
writing utilities, ensuring CLAUDE.md files are created in the correct
project directory regardless of where the worker was started.

Changes:
- Add projectRoot parameter to updateFolderClaudeMdFiles for path resolution
- Thread projectRoot through ResponseProcessor call chain
- Track lastCwd from messages in SDKAgent, GeminiAgent, OpenRouterAgent
- Add tests for relative/absolute path handling with projectRoot

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

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

* more project context updates

* context updates

* fix: preserve actual dates in folder CLAUDE.md generation

Previously, formatTimelineForClaudeMd used today's date for all
observations because the API only returned time (e.g., "4:30 PM")
without date information. This caused all historical observations
to appear as if they happened today.

Changes:
- SearchManager.findByFile now groups results by date with headers
  (e.g., "### Jan 4, 2026") matching formatSearchResults behavior
- formatTimelineForClaudeMd now parses these date headers and uses
  the correct date when constructing epochs for date grouping

The timeline dates are critical for claude-mem context - LLMs need
accurate temporal context to understand when work happened.

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

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

* build: update worker assets with date parsing fix

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

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

* claude-mem context: Fixed critical date parsing bug in PR #556

* fix: address PR #556 review items

- Use getWorkerHost() instead of hard-coded 127.0.0.1 in claude-md-utils
- Add error message and stack details to FOLDER_INDEX logging
- Add 5 new tests for worktree/projectRoot path resolution

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

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

* Refactor CLAUDE documentation across multiple components and tests

- Updated CLAUDE.md files in src/ui/viewer, src/ui/viewer/constants, src/ui/viewer/hooks, tests/server, tests/worker/agents, and plans to reflect recent changes and improvements.
- Removed outdated entries and consolidated recent activities for clarity.
- Enhanced documentation for hooks, settings, and pagination implementations.
- Streamlined test suite documentation for server and worker agents, indicating recent test audits and cleanup efforts.
- Adjusted plans to remove obsolete entries and focus on current implementation strategies.

* docs: comprehensive v9.0 documentation audit and updates

- Add usage/folder-context to docs.json navigation (was documented but hidden!)
- Update introduction.mdx with v9.0 release notes (Live Context, Worktree Support, Windows Fixes)
- Add CLAUDE_MEM_WORKER_HOST setting to configuration.mdx
- Add Folder Context Files section with link to detailed docs
- Document worktree support in folder-context.mdx
- Update terminology from "mem-search skill" to "MCP tools" throughout active docs
- Update Search Pipeline in architecture/overview.mdx
- Update usage/getting-started.mdx with MCP tools terminology
- Update usage/claude-desktop.mdx title and terminology
- Update hooks-architecture.mdx reference

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

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

* feat: add recent activity log for worker CLI with detailed entries

* chore: update CLAUDE.md context files

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

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

* feat: add brainstorming report for CLAUDE.md distribution architecture

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-01-05 22:41:42 -05:00
committed by GitHub
parent 21a1e272d9
commit e1ab73decc
152 changed files with 10367 additions and 2103 deletions
+120
View File
@@ -0,0 +1,120 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 10, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23818 | 10:52 PM | ✅ | Build Script Updated to Bundle Worker CLI with Bun Shebang | ~225 |
| #23817 | " | 🔵 | Build Script Handles Hook Bundling; Worker Shebang Currently Uses Node | ~323 |
| #23793 | 10:14 PM | 🔄 | Smart Install Script Simplified for Clarity | ~479 |
| #23667 | 8:35 PM | 🔵 | Export-Memories Script Structure and Database Query Pattern | ~287 |
| #23649 | 8:13 PM | 🔴 | Fixed Sessions Array Type in Export Script | ~189 |
| #23648 | " | 🔴 | Applied Type Annotations to Export Script Variables | ~305 |
| #23647 | 8:12 PM | 🔴 | Improved Type Safety in Export Script | ~352 |
| #23646 | " | 🔴 | Fixed Variable Shadowing in Export Script | ~234 |
| #23645 | " | 🔵 | Export Script Has Variable Shadowing Issue | ~234 |
| #23644 | 8:11 PM | 🔴 | Added Database Existence Check to Export Script | ~245 |
| #23643 | " | 🔵 | Export Script Opens Database Without Existence Check | ~238 |
| #23642 | " | 🔴 | Fixed Export Script Hardcoded Port - Now Reads from User Settings | ~244 |
| #23641 | " | ✅ | Added Settings Import to Export Script | ~189 |
| #23640 | " | 🔵 | Export Script Has Hardcoded Port Parameter | ~213 |
| #23639 | " | 🔴 | Fixed Import Script insertSession.run() Call Parameters | ~218 |
### Dec 11, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24051 | 2:54 PM | 🟣 | Auto-Restart Worker After Marketplace Sync | ~384 |
| #24050 | " | ✅ | Build Worker Binary Script Made Executable | ~225 |
| #24049 | 2:53 PM | 🟣 | Windows Binary Build Script Created | ~362 |
| #24048 | " | ✅ | MCP Server Shebang Updated to Bun Runtime | ~342 |
| #24047 | " | ✅ | Hook Scripts Shebang Updated to Bun Runtime | ~305 |
| #24046 | " | ✅ | Worker Service Shebang Updated to Bun Runtime | ~306 |
| #24045 | 2:52 PM | 🔵 | Sync Marketplace Script Analysis for Auto-Restart Integration | ~366 |
| #24043 | " | 🔵 | Build Script Analysis for Phase 4 Updates | ~380 |
| #23922 | 1:34 PM | 🔵 | Three Node Shebangs Found in Build Configuration | ~349 |
| #23917 | 1:33 PM | 🔵 | Worker Service Build Configuration Current State | ~365 |
### Dec 12, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24639 | 10:46 PM | 🔴 | Enhanced UV Detection to Support Fresh Installs Before PATH Reload | ~326 |
| #24638 | " | 🔴 | Enhanced Bun Detection to Support Fresh Installs Before PATH Reload | ~338 |
| #24637 | " | 🔵 | Bun Installation Detection Using spawnSync | ~288 |
| #24636 | " | 🔵 | Duplicate Smart Install Scripts in Project Structure | ~288 |
### Dec 14, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #26768 | 11:31 PM | 🔵 | Build Script Generates Empty plugin/package.json Without Postinstall Hook | ~492 |
| #26767 | " | 🔵 | Build Script Generates Empty Plugin Package.json Without Postinstall Hook | ~523 |
| #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 |
| #25815 | 5:31 PM | 🔵 | Comprehensive MCP Server and SKILL.md Structure Analysis | ~575 |
| #25809 | 5:30 PM | 🔵 | Build System Architecture Using esbuild for Component Bundling | ~484 |
### Dec 16, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27725 | 5:45 PM | 🔵 | Export script uses hybrid search API to export observations, sessions, summaries, and prompts | ~335 |
| #27705 | 5:38 PM | ✅ | Switched import-memories.ts from better-sqlite3 to bun:sqlite | ~212 |
### Dec 17, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29052 | 10:02 PM | 🔵 | Sync Script Manages Multiple Plugin Installation Locations | ~394 |
### Dec 18, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29565 | 5:28 PM | ✅ | Output File Changed from code.yaml to code.json | ~234 |
| #29564 | " | 🔄 | Script Refactored to Generate JSON Instead of YAML | ~332 |
### Dec 19, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30109 | 8:11 PM | 🔵 | RAGTIME Script Uses Agent SDK Without Plugin Loading | ~490 |
| #30076 | 8:05 PM | 🔵 | RAGTIME Script Uses Agent SDK Query Function for Email Processing | ~389 |
### Dec 20, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #30340 | 3:42 PM | 🔄 | Relocated simple ragtime.ts to ragtime folder | ~219 |
| #30337 | 3:40 PM | 🔵 | Simplified Ragtime Runner in Scripts Directory | ~456 |
| #30256 | 3:18 PM | 🔵 | Plugin Path Resolution Strategy | ~386 |
| #30250 | 3:17 PM | 🟣 | RAGTIME Email Investigation Runner Implemented | ~503 |
### Dec 26, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32983 | 11:04 PM | 🟣 | Complete build and deployment pipeline executed | ~260 |
### Dec 28, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #33261 | 2:58 PM | 🔄 | Build script cleanup removes obsolete worker-wrapper and worker-cli build steps | ~335 |
### Dec 30, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34460 | 2:23 PM | 🔵 | Build System Architecture Using ESBuild | ~492 |
### Jan 4, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36765 | 12:41 AM | 🔵 | Smart Install Script Path Detection Logic | ~405 |
</claude-mem-context>
+30
View File
@@ -135,3 +135,33 @@ These files are **NEVER** allowed to have catch-and-continue:
- `worker-service.ts` - Core service errors must be visible
On critical paths, prefer **NO TRY-CATCH** and let errors propagate naturally.
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 2, 2026
**detect-error-handling-antipatterns.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #36018 | 9:12 PM | 🔵 | Anti-pattern detection scan shows progress | ~301 |
| #36012 | 9:09 PM | 🔵 | Error Handling Anti-Pattern Detection Baseline | ~222 |
| #36011 | 8:55 PM | 🔄 | Simplified anti-pattern severity levels | ~238 |
| #35810 | 2:15 PM | 🔄 | Relocated Error Handling Detector Script | ~254 |
**CLAUDE.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35901 | 2:49 PM | 🔵 | PR #525 File Changes Summary | ~376 |
| #35812 | 2:15 PM | ✅ | Updated test script path in CLAUDE.md after file relocation | ~298 |
| #35811 | " | ✅ | Created Error Handling Rules Documentation in Test Directory | ~315 |
| #35808 | " | ✅ | Moved CLAUDE.md into anti-pattern-test subfolder | ~140 |
**claude.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #35807 | 2:15 PM | ✅ | Reorganized anti-pattern test files into dedicated subfolder | ~265 |
</claude-mem-context>
+15
View File
@@ -0,0 +1,15 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 30, 2025
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34517 | 2:34 PM | 🔵 | Bug Report Script Successfully Migrated to V2 Pattern | ~388 |
| #34513 | 2:33 PM | ✅ | Phase 4 Utility Scripts Migration Committed and Pushed | ~437 |
| #34512 | " | ✅ | Bug Report Script Migrated to V2 Prompt API | ~524 |
| #34509 | 2:32 PM | 🔵 | Bug Report Script Still Uses V1 SDK Pattern | ~499 |
| #34457 | 2:21 PM | 🔵 | Bug Report Script Using V2 Prompt API | ~325 |
</claude-mem-context>
+562
View File
@@ -0,0 +1,562 @@
#!/usr/bin/env bun
/**
* Regenerate CLAUDE.md files for folders in the current project
*
* Usage:
* bun scripts/regenerate-claude-md.ts [--dry-run] [--clean]
*
* Options:
* --dry-run Show what would be done without writing files
* --clean Remove auto-generated CLAUDE.md files instead of regenerating
*
* Behavior:
* - Scopes to current working directory (not entire database history)
* - Uses git ls-files to respect .gitignore (skips node_modules, .git, etc.)
* - Only processes folders that exist within the current project
* - Filters database to current project observations only
*/
import { Database } from 'bun:sqlite';
import path from 'path';
import os from 'os';
import { existsSync, mkdirSync, writeFileSync, readFileSync, renameSync, unlinkSync, readdirSync } from 'fs';
import { execSync } from 'child_process';
import { SettingsDefaultsManager } from '../src/shared/SettingsDefaultsManager.js';
const DB_PATH = path.join(os.homedir(), '.claude-mem', 'claude-mem.db');
const SETTINGS_PATH = path.join(os.homedir(), '.claude-mem', 'settings.json');
const settings = SettingsDefaultsManager.loadFromFile(SETTINGS_PATH);
const OBSERVATION_LIMIT = parseInt(settings.CLAUDE_MEM_CONTEXT_OBSERVATIONS, 10) || 50;
interface ObservationRow {
id: number;
title: string | null;
subtitle: string | null;
narrative: string | null;
facts: string | null;
type: string;
created_at: string;
created_at_epoch: number;
files_modified: string | null;
files_read: string | null;
project: string;
discovery_tokens: number | null;
}
// Import shared formatting utilities
import { formatTime, groupByDate } from '../src/shared/timeline-formatting.js';
// Type icon map (matches ModeManager)
const TYPE_ICONS: Record<string, string> = {
'bugfix': '🔴',
'feature': '🟣',
'refactor': '🔄',
'change': '✅',
'discovery': '🔵',
'decision': '⚖️',
'session': '🎯',
'prompt': '💬'
};
function getTypeIcon(type: string): string {
return TYPE_ICONS[type] || '📝';
}
function estimateTokens(obs: ObservationRow): number {
const size = (obs.title?.length || 0) +
(obs.subtitle?.length || 0) +
(obs.narrative?.length || 0) +
(obs.facts?.length || 0);
return Math.ceil(size / 4);
}
/**
* Get tracked folders using git ls-files
* This respects .gitignore and only returns folders within the project
*/
function getTrackedFolders(workingDir: string): Set<string> {
const folders = new Set<string>();
try {
// Get all tracked files using git ls-files
const output = execSync('git ls-files', {
cwd: workingDir,
encoding: 'utf-8',
maxBuffer: 50 * 1024 * 1024 // 50MB buffer for large repos
});
const files = output.trim().split('\n').filter(f => f);
for (const file of files) {
// Get the absolute path, then extract directory
const absPath = path.join(workingDir, file);
let dir = path.dirname(absPath);
// Add all parent directories up to (but not including) the working dir
while (dir.length > workingDir.length && dir.startsWith(workingDir)) {
folders.add(dir);
dir = path.dirname(dir);
}
}
} catch (error) {
console.error('Warning: git ls-files failed, falling back to directory walk');
// Fallback: walk directories but skip common ignored patterns
walkDirectoriesWithIgnore(workingDir, folders);
}
return folders;
}
/**
* Fallback directory walker that skips common ignored patterns
*/
function walkDirectoriesWithIgnore(dir: string, folders: Set<string>, depth: number = 0): void {
if (depth > 10) return; // Prevent infinite recursion
const ignorePatterns = [
'node_modules', '.git', '.next', 'dist', 'build', '.cache',
'__pycache__', '.venv', 'venv', '.idea', '.vscode', 'coverage',
'.claude-mem', '.open-next', '.turbo'
];
try {
const entries = readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
if (!entry.isDirectory()) continue;
if (ignorePatterns.includes(entry.name)) continue;
if (entry.name.startsWith('.') && entry.name !== '.claude') continue;
const fullPath = path.join(dir, entry.name);
folders.add(fullPath);
walkDirectoriesWithIgnore(fullPath, folders, depth + 1);
}
} catch {
// Ignore permission errors
}
}
/**
* Check if a file is a direct child of a folder (not in a subfolder)
* @param filePath - File path like "src/services/foo.ts"
* @param folderPath - Folder path like "src/services"
* @returns true if file is directly in folder, false if in a subfolder
*/
function isDirectChild(filePath: string, folderPath: string): boolean {
if (!filePath.startsWith(folderPath + '/')) return false;
const remainder = filePath.slice(folderPath.length + 1);
// If remainder contains a slash, it's in a subfolder
return !remainder.includes('/');
}
/**
* Check if an observation has any files that are direct children of the folder
*/
function hasDirectChildFile(obs: ObservationRow, folderPath: string): boolean {
const checkFiles = (filesJson: string | null): boolean => {
if (!filesJson) return false;
try {
const files = JSON.parse(filesJson);
if (Array.isArray(files)) {
return files.some(f => isDirectChild(f, folderPath));
}
} catch {}
return false;
};
return checkFiles(obs.files_modified) || checkFiles(obs.files_read);
}
/**
* Query observations for a specific folder
* folderPath is a relative path from the project root (e.g., "src/services")
* Only returns observations with files directly in the folder (not in subfolders)
*/
function findObservationsByFolder(db: Database, relativeFolderPath: string, project: string, limit: number): ObservationRow[] {
// Query more results than needed since we'll filter some out
const queryLimit = limit * 3;
const sql = `
SELECT o.*, o.discovery_tokens
FROM observations o
WHERE o.project = ?
AND (o.files_modified LIKE ? OR o.files_read LIKE ?)
ORDER BY o.created_at_epoch DESC
LIMIT ?
`;
// Files in DB are stored as relative paths like "src/services/foo.ts"
// Match any file that starts with this folder path (we'll filter to direct children below)
const likePattern = `%"${relativeFolderPath}/%`;
const allMatches = db.prepare(sql).all(project, likePattern, likePattern, queryLimit) as ObservationRow[];
// Filter to only observations with direct child files (not in subfolders)
return allMatches.filter(obs => hasDirectChildFile(obs, relativeFolderPath)).slice(0, limit);
}
/**
* Extract relevant file from an observation for display
* Only returns files that are direct children of the folder (not in subfolders)
* @param obs - The observation row
* @param relativeFolder - Relative folder path (e.g., "src/services")
*/
function extractRelevantFile(obs: ObservationRow, relativeFolder: string): string {
// Try files_modified first - only direct children
if (obs.files_modified) {
try {
const modified = JSON.parse(obs.files_modified);
if (Array.isArray(modified) && modified.length > 0) {
for (const file of modified) {
if (isDirectChild(file, relativeFolder)) {
// Get just the filename (no path since it's a direct child)
return path.basename(file);
}
}
}
} catch {}
}
// Fall back to files_read - only direct children
if (obs.files_read) {
try {
const read = JSON.parse(obs.files_read);
if (Array.isArray(read) && read.length > 0) {
for (const file of read) {
if (isDirectChild(file, relativeFolder)) {
return path.basename(file);
}
}
}
} catch {}
}
return 'General';
}
/**
* Format observations for CLAUDE.md content
*/
function formatObservationsForClaudeMd(observations: ObservationRow[], folderPath: string): string {
const lines: string[] = [];
lines.push('# Recent Activity');
lines.push('');
lines.push('<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->');
lines.push('');
if (observations.length === 0) {
lines.push('*No recent activity*');
return lines.join('\n');
}
const byDate = groupByDate(observations, obs => obs.created_at);
for (const [day, dayObs] of byDate) {
lines.push(`### ${day}`);
lines.push('');
const byFile = new Map<string, ObservationRow[]>();
for (const obs of dayObs) {
const file = extractRelevantFile(obs, folderPath);
if (!byFile.has(file)) byFile.set(file, []);
byFile.get(file)!.push(obs);
}
for (const [file, fileObs] of byFile) {
lines.push(`**${file}**`);
lines.push('| ID | Time | T | Title | Read |');
lines.push('|----|------|---|-------|------|');
let lastTime = '';
for (const obs of fileObs) {
const time = formatTime(obs.created_at_epoch);
const timeDisplay = time === lastTime ? '"' : time;
lastTime = time;
const icon = getTypeIcon(obs.type);
const title = obs.title || 'Untitled';
const tokens = estimateTokens(obs);
lines.push(`| #${obs.id} | ${timeDisplay} | ${icon} | ${title} | ~${tokens} |`);
}
lines.push('');
}
}
return lines.join('\n').trim();
}
/**
* Write CLAUDE.md file with tagged content preservation
*/
function writeClaudeMdToFolder(folderPath: string, newContent: string): void {
const claudeMdPath = path.join(folderPath, 'CLAUDE.md');
const tempFile = `${claudeMdPath}.tmp`;
mkdirSync(folderPath, { recursive: true });
let existingContent = '';
if (existsSync(claudeMdPath)) {
existingContent = readFileSync(claudeMdPath, 'utf-8');
}
const startTag = '<claude-mem-context>';
const endTag = '</claude-mem-context>';
let finalContent: string;
if (!existingContent) {
finalContent = `${startTag}\n${newContent}\n${endTag}`;
} else {
const startIdx = existingContent.indexOf(startTag);
const endIdx = existingContent.indexOf(endTag);
if (startIdx !== -1 && endIdx !== -1) {
finalContent = existingContent.substring(0, startIdx) +
`${startTag}\n${newContent}\n${endTag}` +
existingContent.substring(endIdx + endTag.length);
} else {
finalContent = existingContent + `\n\n${startTag}\n${newContent}\n${endTag}`;
}
}
writeFileSync(tempFile, finalContent);
renameSync(tempFile, claudeMdPath);
}
/**
* Clean up auto-generated CLAUDE.md files
*
* For each file with <claude-mem-context> tags:
* - Strip the tagged section
* - If empty after stripping → delete the file
* - If has remaining content → save the stripped version
*/
function cleanupAutoGeneratedFiles(workingDir: string, dryRun: boolean): void {
console.log('=== CLAUDE.md Cleanup Mode ===\n');
console.log(`Scanning ${workingDir} for CLAUDE.md files with auto-generated content...\n`);
const filesToProcess: string[] = [];
// Walk directories to find CLAUDE.md files
function walkForClaudeMd(dir: string): void {
const ignorePatterns = ['node_modules', '.git', '.next', 'dist', 'build'];
try {
const entries = readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
if (!ignorePatterns.includes(entry.name)) {
walkForClaudeMd(fullPath);
}
} else if (entry.name === 'CLAUDE.md') {
// Check if file contains auto-generated content
try {
const content = readFileSync(fullPath, 'utf-8');
if (content.includes('<claude-mem-context>')) {
filesToProcess.push(fullPath);
}
} catch {
// Skip files we can't read
}
}
}
} catch {
// Ignore permission errors
}
}
walkForClaudeMd(workingDir);
if (filesToProcess.length === 0) {
console.log('No CLAUDE.md files with auto-generated content found.');
return;
}
console.log(`Found ${filesToProcess.length} CLAUDE.md files with auto-generated content:\n`);
let deletedCount = 0;
let cleanedCount = 0;
let errorCount = 0;
for (const file of filesToProcess) {
const relativePath = path.relative(workingDir, file);
try {
const content = readFileSync(file, 'utf-8');
// Strip the claude-mem-context tagged section
const stripped = content.replace(/<claude-mem-context>[\s\S]*?<\/claude-mem-context>/g, '').trim();
if (stripped === '') {
// Empty after stripping → delete
if (dryRun) {
console.log(` [DRY-RUN] Would delete (empty): ${relativePath}`);
} else {
unlinkSync(file);
console.log(` Deleted (empty): ${relativePath}`);
}
deletedCount++;
} else {
// Has content → write stripped version
if (dryRun) {
console.log(` [DRY-RUN] Would clean: ${relativePath}`);
} else {
writeFileSync(file, stripped);
console.log(` Cleaned: ${relativePath}`);
}
cleanedCount++;
}
} catch (error) {
console.error(` Error processing ${relativePath}: ${error}`);
errorCount++;
}
}
console.log('\n=== Summary ===');
console.log(`Deleted (empty): ${deletedCount}`);
console.log(`Cleaned: ${cleanedCount}`);
console.log(`Errors: ${errorCount}`);
if (dryRun) {
console.log('\nRun without --dry-run to actually process files.');
}
}
/**
* Regenerate CLAUDE.md for a single folder
* @param absoluteFolder - Absolute path for writing files
* @param relativeFolder - Relative path for DB queries (matches storage format)
*/
function regenerateFolder(
db: Database,
absoluteFolder: string,
relativeFolder: string,
project: string,
dryRun: boolean
): { success: boolean; observationCount: number; error?: string } {
try {
// Query using relative path (matches DB storage format)
const observations = findObservationsByFolder(db, relativeFolder, project, OBSERVATION_LIMIT);
if (observations.length === 0) {
return { success: false, observationCount: 0, error: 'No observations for folder' };
}
if (dryRun) {
return { success: true, observationCount: observations.length };
}
// Format using relative path for display, write to absolute path
const formatted = formatObservationsForClaudeMd(observations, relativeFolder);
writeClaudeMdToFolder(absoluteFolder, formatted);
return { success: true, observationCount: observations.length };
} catch (error) {
return { success: false, observationCount: 0, error: String(error) };
}
}
/**
* Main function
*/
async function main() {
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');
const cleanMode = args.includes('--clean');
const workingDir = process.cwd();
// Handle cleanup mode
if (cleanMode) {
cleanupAutoGeneratedFiles(workingDir, dryRun);
return;
}
console.log('=== CLAUDE.md Regeneration Script ===\n');
console.log(`Working directory: ${workingDir}`);
// Determine project identifier (matches how hooks determine project - uses folder name)
const project = path.basename(workingDir);
console.log(`Project: ${project}\n`);
// Get tracked folders using git ls-files
console.log('Discovering folders (using git ls-files to respect .gitignore)...');
const trackedFolders = getTrackedFolders(workingDir);
if (trackedFolders.size === 0) {
console.log('No folders found in project.');
process.exit(0);
}
console.log(`Found ${trackedFolders.size} folders in project.\n`);
// Open database
if (!existsSync(DB_PATH)) {
console.log('Database not found. No observations to process.');
process.exit(0);
}
console.log('Opening database...');
const db = new Database(DB_PATH, { readonly: true, create: false });
if (dryRun) {
console.log('[DRY RUN] Would regenerate the following folders:\n');
}
// Process each folder
let successCount = 0;
let skipCount = 0;
let errorCount = 0;
const foldersArray = Array.from(trackedFolders).sort();
for (let i = 0; i < foldersArray.length; i++) {
const absoluteFolder = foldersArray[i];
const progress = `[${i + 1}/${foldersArray.length}]`;
const relativeFolder = path.relative(workingDir, absoluteFolder);
if (dryRun) {
// Query using relative path (matches DB storage format)
const observations = findObservationsByFolder(db, relativeFolder, project, OBSERVATION_LIMIT);
if (observations.length > 0) {
console.log(`${progress} ${relativeFolder} (${observations.length} obs)`);
successCount++;
} else {
skipCount++;
}
continue;
}
const result = regenerateFolder(db, absoluteFolder, relativeFolder, project, dryRun);
if (result.success) {
console.log(`${progress} ${relativeFolder} - ${result.observationCount} obs`);
successCount++;
} else if (result.error?.includes('No observations')) {
skipCount++;
} else {
console.log(`${progress} ${relativeFolder} - ERROR: ${result.error}`);
errorCount++;
}
}
db.close();
// Summary
console.log('\n=== Summary ===');
console.log(`Total folders scanned: ${foldersArray.length}`);
console.log(`With observations: ${successCount}`);
console.log(`No observations: ${skipCount}`);
console.log(`Errors: ${errorCount}`);
if (dryRun) {
console.log('\nRun without --dry-run to actually regenerate files.');
}
}
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});
+145
View File
@@ -0,0 +1,145 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Dec 12, 2025
**cli.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24246 | 2:43 AM | 🟣 | Comprehensive Translation System Added with 22 Language READMEs | ~386 |
| #24235 | 2:32 AM | 🔵 | Translation CLI Script Structure | ~267 |
| #24215 | 1:49 AM | 🟣 | Wired parallel argument to translateReadme function call | ~290 |
| #24214 | " | 🟣 | Implemented --parallel argument parsing with validation | ~271 |
| #24213 | " | 🟣 | Initialized parallel default value in parseArgs | ~212 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #24236 | 2:33 AM | 🔵 | Translation Core Logic and Output Directory Handling | ~288 |
| #24219 | 1:50 AM | 🟣 | Implemented concurrent translation processing with parallelism control | ~461 |
| #24218 | " | 🟣 | Extracted parallel parameter in translateReadme function | ~259 |
| #24217 | " | 🔵 | Current translateReadme uses sequential for-loop processing | ~312 |
| #24216 | " | 🟣 | Added parallel option to TranslationOptions interface | ~262 |
### Dec 13, 2025
**examples.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #25321 | 9:12 PM | 🔵 | Console.error Usage Found in 29 Files | ~366 |
### Dec 14, 2025
**cli.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #25670 | 3:42 PM | 🔵 | Translation System Supports 38 Languages | ~259 |
| #25668 | 3:40 PM | 🟣 | Translation system enhancement with 226 net line addition | ~298 |
| #25667 | " | 🔵 | Translation script CLI interface and authentication | ~330 |
| #25664 | 3:39 PM | 🔵 | Modified files from PR-250 cherry-pick | ~238 |
| #25663 | " | 🔵 | Translation script structure with CLI and examples | ~277 |
**translate-readme**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #25660 | 3:38 PM | ✅ | Cherry-picked translation script from PR-250 branch | ~192 |
### Dec 15, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27161 | 8:08 PM | 🔵 | README Translation Script Architecture | ~420 |
| #27158 | " | 🔵 | Complete API Key Authentication Flow Traced Through System | ~460 |
**examples.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #27149 | 8:07 PM | 🔵 | API Key Management Implementation Details | ~302 |
| #27146 | " | 🔵 | ANTHROPIC_API_KEY Referenced Across Documentation and Scripts | ~254 |
### Dec 18, 2025
**README.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #29244 | 12:15 AM | 🔵 | Identified YAML configuration files in claude-mem project | ~164 |
### 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 |
|----|------|---|-------|------|
| #31753 | 11:01 PM | 🔵 | README Translation CLI Tool Verified Operational | ~349 |
| #31749 | 10:57 PM | 🔵 | CLI del traductor de README incluye opción de paralelización | ~317 |
| #31713 | 9:41 PM | 🔵 | Complete Multilingual Infrastructure Documented | ~545 |
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31752 | 10:59 PM | 🔴 | Fixed concurrency control bug in translation script | ~309 |
| #31751 | 10:58 PM | 🔵 | Concurrencia implementada con función runWithConcurrency personalizada | ~483 |
| #31748 | 10:57 PM | 🔵 | Ubicación del script traductor de README identificada | ~241 |
| #31601 | 8:19 PM | 🔵 | 215 console logging statements in TypeScript utility scripts | ~501 |
**README.md**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31750 | 10:58 PM | 🔵 | Documentación del traductor de README no menciona concurrencia | ~292 |
### Dec 22, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31921 | 7:36 PM | ✅ | Updated Verbose Output to Always Show Parallel Count | ~233 |
| #31920 | " | 🟣 | Implemented Always-On Concurrent Translation with 10-Worker Limit | ~280 |
| #31919 | " | ✅ | Removed Parallel Parameter from TranslationOptions Interface | ~198 |
| #31918 | " | 🔵 | Translation Engine Uses Configurable Concurrency Control | ~322 |
**cli.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #31917 | 7:35 PM | 🔵 | Current CLI Implementation Uses Optional Parallel Flag | ~237 |
### Dec 23, 2025
**cli.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #32292 | 7:19 PM | ✅ | Removed parallel parameter from CLI arguments interface | ~189 |
| #32308 | " | ✅ | Removed parallel default value from argument parser initialization | ~181 |
| #32321 | " | ✅ | Removed --parallel flag parsing from CLI argument parser | ~225 |
| #32328 | " | ✅ | Removed parallel parameter from translateReadme function call | ~205 |
| #32335 | " | ✅ | Updated CLI help documentation to reflect automatic parallel execution | ~261 |
### Dec 30, 2025
**index.ts**
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #34507 | 2:32 PM | 🟣 | Completed V2 Migration of Translation Script | ~394 |
| #34501 | 2:30 PM | ✅ | Started V2 Migration of Translation Script Import | ~270 |
| #34498 | " | 🔵 | Translation Script Uses V1 SDK Query API | ~409 |
| #34445 | 2:19 PM | 🔵 | Translation Script Already Using V2 API | ~264 |
| #34405 | 1:54 PM | 🔵 | Translation Script Using V1 SDK API | ~367 |
### 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 |
| #34568 | " | 🔵 | Utility Script V2 Migration Used Incorrect systemPrompt Option | ~425 |
</claude-mem-context>
+16
View File
@@ -0,0 +1,16 @@
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### Jan 4, 2026
**export.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 |
| #36844 | 1:44 AM | 🔵 | Shared Type Definitions for Export/Import Operations | ~502 |
| #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 |
</claude-mem-context>