Skip to content

Conversation

@ThanhNguyxn
Copy link

Summary

Implements feature request from #180 - adds the ability to include the most recent plan file from ~/.claude/plans/ in the context injection.

Changes

Backend - Settings Infrastructure

  • SettingsDefaultsManager.ts: Added CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN setting (default: false)

Backend - Context Generator

  • context-generator.ts:
    • Added getMostRecentPlanFile() helper function to read the latest .md file from ~/.claude/plans/
    • Extracts plan title from H1 heading
    • Injects plan content into context output when toggle is enabled

Backend - Settings API

  • SettingsRoutes.ts: Added the new setting key to allowed settings list and boolean validation

Frontend - UI Types

  • types.ts: Added CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN to Settings interface

How It Works

  1. User enables CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN in settings (via ~/.claude-mem/settings.json or future UI toggle)
  2. On SessionStart, context-generator reads ~/.claude/plans/ directory
  3. Most recent .md file (by modification time) is selected
  4. Plan title is extracted from the first H1 heading
  5. Full plan content is injected into context with header showing title and file path

Example Output

---

**📋 Last Plan: Fix Authentication Flow**
_File: /home/user/.claude/plans/federated-wandering-volcano.md_

# Fix Authentication Flow

## Steps
1. Update token validation...

Testing

  • ✅ Follows existing settings pattern
  • ✅ Graceful handling when no plans exist
  • ✅ Error logging for file read failures

Closes #180

- Add CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN setting (default: false)
- Implement getMostRecentPlanFile() to read latest plan from ~/.claude/plans/
- Inject plan content into context when toggle is enabled
- Add setting validation and UI type support

Closes thedotmack#180
Copilot AI review requested due to automatic review settings December 12, 2025 08:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds the ability to inject the most recent plan file from ~/.claude/plans/ into the context when enabled via a new setting CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN. The implementation follows the existing pattern used for CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY and CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE.

Key Changes

  • Added new toggle setting CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN (defaults to false)
  • Implemented plan file discovery and content injection in context generator
  • Extracts plan title from H1 heading for display

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/ui/viewer/types.ts Added CLAUDE_MEM_CONTEXT_SHOW_LAST_PLAN property to Settings interface
src/shared/SettingsDefaultsManager.ts Added default value for new setting (false) in SettingsDefaults interface and DEFAULTS object
src/services/worker/http/routes/SettingsRoutes.ts Added new setting to allowed keys list and boolean validation
src/services/context-generator.ts Implemented getMostRecentPlanFile() helper function and integrated plan content injection into context output, plus minor indentation formatting improvements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 279 to 283
.map((f: string) => ({
name: f,
path: path.join(plansDir, f),
mtime: statSync(path.join(plansDir, f)).mtime.getTime()
}))
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statSync call is being made twice for each file - once in the map function to get the full path and again to retrieve mtime. This can be optimized by first constructing the full path, then calling statSync once per file. Consider restructuring to avoid the redundant filesystem calls.

Suggested change
.map((f: string) => ({
name: f,
path: path.join(plansDir, f),
mtime: statSync(path.join(plansDir, f)).mtime.getTime()
}))
.map((f: string) => {
const fullPath = path.join(plansDir, f);
const stat = statSync(fullPath);
return {
name: f,
path: fullPath,
mtime: stat.mtime.getTime()
};
})

Copilot uses AI. Check for mistakes.

// Extract title from H1 heading
const titleMatch = content.match(/^#\s+(.+)$/m);
const title = titleMatch?.[1] || mostRecent.name.replace('.md', '');
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern /^#\s+(.+)$/m will match the first H1 heading anywhere in the file, but it could match a heading with trailing whitespace. Consider trimming the captured title with .trim() to ensure clean titles, like: const title = titleMatch?.[1]?.trim() || mostRecent.name.replace('.md', '');

Suggested change
const title = titleMatch?.[1] || mostRecent.name.replace('.md', '');
const title = titleMatch?.[1]?.trim() || mostRecent.name.replace('.md', '');

Copilot uses AI. Check for mistakes.
Address Copilot review suggestion - restructure map function
to avoid redundant filesystem calls by only calling statSync
once per file instead of twice.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Reading Plan File of Last Session

1 participant