claude-self-reflect 2.4.2 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -416,6 +416,43 @@ gh run watch # This will show the CI/CD pipeline publishing to npm
416
416
  # Check GitHub releases, npm package, and that all PRs were closed properly."
417
417
  ```
418
418
 
419
+ ### Handling GitHub API Timeouts
420
+ **CRITICAL LEARNING**: 504 Gateway Timeout doesn't mean the operation failed!
421
+
422
+ When you encounter HTTP 504 Gateway Timeout errors from GitHub API:
423
+ 1. **DO NOT immediately retry** - The operation may have succeeded on the backend
424
+ 2. **ALWAYS check if the operation completed** before attempting again
425
+ 3. **Wait and verify** - Check the actual state (discussions, releases, etc.)
426
+
427
+ Example with GitHub Discussions:
428
+ ```bash
429
+ # If you get a 504 timeout when creating a discussion:
430
+ # 1. Wait a moment
431
+ # 2. Check if it was created despite the timeout:
432
+ gh api graphql -f query='
433
+ query {
434
+ repository(owner: "owner", name: "repo") {
435
+ discussions(first: 5) {
436
+ nodes {
437
+ title
438
+ createdAt
439
+ }
440
+ }
441
+ }
442
+ }'
443
+
444
+ # Common scenario: GraphQL mutations that timeout but succeed
445
+ # - createDiscussion with large body content
446
+ # - Complex release operations
447
+ # - Bulk PR operations
448
+ ```
449
+
450
+ **Best Practices for API Operations:**
451
+ 1. For large content (discussions, releases), use minimal initial creation
452
+ 2. Add detailed content in subsequent updates if needed
453
+ 3. Always verify operation status after timeouts
454
+ 4. Keep operation logs to track what actually succeeded
455
+
419
456
  ## Communication Channels
420
457
 
421
458
  - GitHub Issues: Primary support channel
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: reflect-tester
3
3
  description: Comprehensive testing specialist for validating reflection system functionality. Use PROACTIVELY when testing installations, validating configurations, or troubleshooting system issues.
4
- tools: Read, Bash, Grep, LS, WebFetch, ListMcpResourcesTool
4
+ tools: Read, Bash, Grep, LS, WebFetch, ListMcpResourcesTool, mcp__claude-self-reflect__reflect_on_past, mcp__claude-self-reflect__store_reflection
5
5
  ---
6
6
 
7
7
  # Reflect Tester Agent
@@ -132,6 +132,28 @@ curl -s http://localhost:6333/collections | jq '.result.collections[] | {name, v
132
132
 
133
133
  #### 5.2 Tool Functionality Tests
134
134
 
135
+ **Project-Scoped Search Test (NEW)**:
136
+ Test the new project-scoped search functionality:
137
+
138
+ ```python
139
+ # Test 1: Default search (project-scoped)
140
+ # Should only return results from current project
141
+ results = await reflect_on_past("Docker setup", limit=5, min_score=0.0)
142
+ # Verify: All results should be from current project (claude-self-reflect)
143
+
144
+ # Test 2: Explicit project search
145
+ results = await reflect_on_past("Docker setup", project="claude-self-reflect", limit=5, min_score=0.0)
146
+ # Should match Test 1 results
147
+
148
+ # Test 3: Cross-project search
149
+ results = await reflect_on_past("Docker setup", project="all", limit=5, min_score=0.0)
150
+ # Should include results from multiple projects
151
+
152
+ # Test 4: Different project search
153
+ results = await reflect_on_past("configuration", project="reflections", limit=5, min_score=0.0)
154
+ # Should only return results from the "reflections" project
155
+ ```
156
+
135
157
  **Local Embeddings Test**:
136
158
  ```python
137
159
  # Store reflection with local embeddings
@@ -41,7 +41,7 @@ You are a conversation memory specialist for the Claude Self Reflect project. Yo
41
41
  Search for relevant past conversations using semantic similarity.
42
42
 
43
43
  ```javascript
44
- // Basic search
44
+ // Basic search (searches current project by default)
45
45
  {
46
46
  query: "streaming importer fixes",
47
47
  limit: 5,
@@ -55,8 +55,29 @@ Search for relevant past conversations using semantic similarity.
55
55
  min_score: 0.05, // Common threshold for relevant results
56
56
  use_decay: 1 // Apply time-based relevance (1=enable, 0=disable, -1=default)
57
57
  }
58
+
59
+ // Search specific project (NEW in v2.4.3)
60
+ {
61
+ query: "Docker setup",
62
+ project: "ShopifyMCPMockShop", // Use actual folder name
63
+ limit: 5
64
+ }
65
+
66
+ // Cross-project search (NEW in v2.4.3)
67
+ {
68
+ query: "error handling patterns",
69
+ project: "all", // Search across all projects
70
+ limit: 10
71
+ }
58
72
  ```
59
73
 
74
+ #### Default Behavior: Project-Scoped Search (NEW in v2.4.3)
75
+ **IMPORTANT**: Searches are now scoped to the current project by default:
76
+ - Auto-detects current project from your working directory
77
+ - Only returns results from that project unless you specify otherwise
78
+ - Use `project: "all"` to explicitly search across all projects
79
+ - Use `project: "ProjectName"` to search a specific project (use the actual folder name)
80
+
60
81
  ### store_reflection
61
82
  Save important insights and decisions for future retrieval.
62
83
 
@@ -90,28 +111,236 @@ Save important insights and decisions for future retrieval.
90
111
  4. **Use Context**: Include technology names, error messages, or specific terms
91
112
  5. **Cross-Project When Needed**: Similar problems may have been solved elsewhere
92
113
 
93
- ## Response Best Practices
114
+ ## Response Format
115
+
116
+ ### XML-Structured Output
117
+ To facilitate better parsing and metadata handling, structure your responses using XML format:
118
+
119
+ ```xml
120
+ <reflection-search>
121
+ <summary>
122
+ <query>original search query</query>
123
+ <scope>current|all|project-name</scope>
124
+ <total-results>number</total-results>
125
+ <score-range>min-max</score-range>
126
+ <embedding-type>local|voyage</embedding-type>
127
+ </summary>
128
+
129
+ <results>
130
+ <result rank="1">
131
+ <score>0.725</score>
132
+ <project>ProjectName</project>
133
+ <timestamp>X days ago</timestamp>
134
+ <title>Brief descriptive title</title>
135
+ <key-finding>One-line summary of the main insight</key-finding>
136
+ <excerpt>Most relevant quote or context from the conversation</excerpt>
137
+ <conversation-id>optional-id</conversation-id>
138
+ </result>
139
+
140
+ <result rank="2">
141
+ <!-- Additional results follow same structure -->
142
+ </result>
143
+ </results>
144
+
145
+ <analysis>
146
+ <patterns>Common themes or patterns identified across results</patterns>
147
+ <recommendations>Suggested actions based on findings</recommendations>
148
+ <cross-project-insights>Insights when searching across projects</cross-project-insights>
149
+ </analysis>
150
+
151
+ <metadata>
152
+ <search-latency-ms>optional performance metric</search-latency-ms>
153
+ <collections-searched>number of collections</collections-searched>
154
+ <decay-applied>true|false</decay-applied>
155
+ </metadata>
156
+ </reflection-search>
157
+ ```
94
158
 
95
- ### When Presenting Search Results
96
- 1. **Summarize First**: Brief overview of findings
97
- 2. **Show Relevant Excerpts**: Most pertinent parts with context
98
- 3. **Provide Timeline**: When discussions occurred
99
- 4. **Connect Dots**: How different conversations relate
100
- 5. **Suggest Next Steps**: Based on historical patterns
159
+ ### Response Best Practices
160
+
161
+ 1. **Always use XML structure** for main content
162
+ 2. **Indicate Search Scope** in the summary section
163
+ 3. **Order results by relevance** (highest score first)
164
+ 4. **Include actionable insights** in the analysis section
165
+ 5. **Provide metadata** for transparency
166
+
167
+ ### Proactive Cross-Project Search Suggestions
168
+
169
+ When to suggest searching across all projects:
170
+ - Current project search returns 0-2 results
171
+ - User's query implies looking for patterns or best practices
172
+ - The topic is generic enough to benefit from broader examples
173
+ - User explicitly mentions comparing or learning from other implementations
174
+
175
+ ### Example Response Formats
176
+
177
+ #### When Current Project Has Good Results:
178
+ ```xml
179
+ <reflection-search>
180
+ <summary>
181
+ <query>authentication flow</query>
182
+ <scope>ShopifyMCPMockShop</scope>
183
+ <total-results>3</total-results>
184
+ <score-range>0.15-0.45</score-range>
185
+ <embedding-type>local</embedding-type>
186
+ </summary>
187
+
188
+ <results>
189
+ <result rank="1">
190
+ <score>0.45</score>
191
+ <project>ShopifyMCPMockShop</project>
192
+ <timestamp>2 days ago</timestamp>
193
+ <title>OAuth Implementation Discussion</title>
194
+ <key-finding>Implemented OAuth2 with refresh token rotation</key-finding>
195
+ <excerpt>We decided to use refresh token rotation for better security...</excerpt>
196
+ </result>
197
+ <!-- More results -->
198
+ </results>
199
+
200
+ <analysis>
201
+ <patterns>Authentication consistently uses OAuth2 with JWT tokens</patterns>
202
+ <recommendations>Continue with the established OAuth2 pattern for consistency</recommendations>
203
+ </analysis>
204
+ </reflection-search>
205
+ ```
101
206
 
102
- ### Example Response Format
207
+ #### When Current Project Has Limited Results:
208
+ ```xml
209
+ <reflection-search>
210
+ <summary>
211
+ <query>specific feature implementation</query>
212
+ <scope>CurrentProject</scope>
213
+ <total-results>1</total-results>
214
+ <score-range>0.12</score-range>
215
+ <embedding-type>local</embedding-type>
216
+ </summary>
217
+
218
+ <results>
219
+ <result rank="1">
220
+ <score>0.12</score>
221
+ <project>CurrentProject</project>
222
+ <timestamp>5 days ago</timestamp>
223
+ <title>Initial Feature Discussion</title>
224
+ <key-finding>Considered implementing but deferred</key-finding>
225
+ <excerpt>We discussed this feature but decided to wait...</excerpt>
226
+ </result>
227
+ </results>
228
+
229
+ <analysis>
230
+ <patterns>Limited history in current project</patterns>
231
+ <recommendations>Consider searching across all projects for similar implementations</recommendations>
232
+ <cross-project-insights>Other projects may have relevant patterns</cross-project-insights>
233
+ </analysis>
234
+
235
+ <suggestion>
236
+ <action>search-all-projects</action>
237
+ <reason>Limited results in current project - broader search may reveal useful patterns</reason>
238
+ </suggestion>
239
+ </reflection-search>
103
240
  ```
104
- I found 3 relevant conversations about [topic]:
105
241
 
106
- **1. [Brief Title]** (X days ago)
107
- Project: [project-name]
108
- Key Finding: [One-line summary]
109
- Excerpt: "[Most relevant quote]"
242
+ #### When No Results in Current Project:
243
+ ```xml
244
+ <reflection-search>
245
+ <summary>
246
+ <query>new feature concept</query>
247
+ <scope>CurrentProject</scope>
248
+ <total-results>0</total-results>
249
+ <score-range>N/A</score-range>
250
+ <embedding-type>local</embedding-type>
251
+ </summary>
252
+
253
+ <results>
254
+ <!-- No results found -->
255
+ </results>
256
+
257
+ <analysis>
258
+ <patterns>No prior discussions found</patterns>
259
+ <recommendations>This appears to be a new topic for this project</recommendations>
260
+ </analysis>
261
+
262
+ <suggestions>
263
+ <suggestion>
264
+ <action>search-all-projects</action>
265
+ <reason>Check if similar implementations exist in other projects</reason>
266
+ </suggestion>
267
+ <suggestion>
268
+ <action>store-reflection</action>
269
+ <reason>Document this new implementation for future reference</reason>
270
+ </suggestion>
271
+ </suggestions>
272
+ </reflection-search>
273
+ ```
274
+
275
+ ### Error Response Formats
276
+
277
+ #### Validation Errors
278
+ ```xml
279
+ <reflection-search>
280
+ <error>
281
+ <type>validation-error</type>
282
+ <message>Invalid parameter value</message>
283
+ <details>
284
+ <parameter>min_score</parameter>
285
+ <value>2.5</value>
286
+ <constraint>Must be between 0.0 and 1.0</constraint>
287
+ </details>
288
+ </error>
289
+ </reflection-search>
290
+ ```
291
+
292
+ #### Connection Errors
293
+ ```xml
294
+ <reflection-search>
295
+ <error>
296
+ <type>connection-error</type>
297
+ <message>Unable to connect to Qdrant</message>
298
+ <details>
299
+ <url>http://localhost:6333</url>
300
+ <suggestion>Check if Qdrant is running: docker ps | grep qdrant</suggestion>
301
+ </details>
302
+ </error>
303
+ </reflection-search>
304
+ ```
305
+
306
+ #### Empty Query Error
307
+ ```xml
308
+ <reflection-search>
309
+ <error>
310
+ <type>validation-error</type>
311
+ <message>Query cannot be empty</message>
312
+ <suggestion>Provide a search query to find relevant conversations</suggestion>
313
+ </error>
314
+ </reflection-search>
315
+ ```
110
316
 
111
- **2. [Brief Title]** (Y days ago)
112
- ...
317
+ #### Project Not Found
318
+ ```xml
319
+ <reflection-search>
320
+ <error>
321
+ <type>project-not-found</type>
322
+ <message>Project not found</message>
323
+ <details>
324
+ <requested-project>NonExistentProject</requested-project>
325
+ <available-projects>project1, project2, project3</available-projects>
326
+ <suggestion>Use one of the available projects or 'all' to search across all projects</suggestion>
327
+ </details>
328
+ </error>
329
+ </reflection-search>
330
+ ```
113
331
 
114
- Based on these past discussions, [recommendation or insight].
332
+ #### Rate Limit Error
333
+ ```xml
334
+ <reflection-search>
335
+ <error>
336
+ <type>rate-limit</type>
337
+ <message>API rate limit exceeded</message>
338
+ <details>
339
+ <retry-after>60</retry-after>
340
+ <suggestion>Wait 60 seconds before retrying</suggestion>
341
+ </details>
342
+ </error>
343
+ </reflection-search>
115
344
  ```
116
345
 
117
346
  ## Memory Decay Insights
package/README.md CHANGED
@@ -123,6 +123,51 @@ Once installed, just talk naturally:
123
123
 
124
124
  The reflection specialist automatically activates. No special commands needed.
125
125
 
126
+ ## Project-Scoped Search (New in v2.4.3)
127
+
128
+ **⚠️ Breaking Change**: Searches now default to current project only. Previously searched all projects.
129
+
130
+ Conversations are now **project-aware by default**. When you ask about past conversations, Claude automatically searches within your current project directory, keeping results focused and relevant.
131
+
132
+ ### How It Works
133
+
134
+ ```
135
+ # Example: Working in ~/projects/ShopifyMCPMockShop
136
+ You: "What authentication method did we implement?"
137
+ Claude: [Searches ONLY ShopifyMCPMockShop conversations]
138
+ "Found 3 conversations about JWT authentication..."
139
+
140
+ # To search everywhere (like pre-v2.4.3 behavior)
141
+ You: "Search all projects for WebSocket implementations"
142
+ Claude: [Searches across ALL your projects]
143
+ "Found implementations in 5 projects: ..."
144
+
145
+ # To search a specific project
146
+ You: "Find Docker setup in claude-self-reflect project"
147
+ Claude: [Searches only claude-self-reflect conversations]
148
+ ```
149
+
150
+ ### Key Behaviors
151
+
152
+ | Search Type | How to Trigger | Example |
153
+ |------------|----------------|---------|
154
+ | **Current Project** (default) | Just ask normally | "What did we discuss about caching?" |
155
+ | **All Projects** | Say "all projects" or "across projects" | "Search all projects for error handling" |
156
+ | **Specific Project** | Mention the project name | "Find auth code in MyApp project" |
157
+
158
+ ### Why This Change?
159
+
160
+ - **Focused Results**: No more sifting through unrelated conversations
161
+ - **Better Performance**: Single-project search is ~100ms faster
162
+ - **Natural Workflow**: Results match your current working context
163
+ - **Privacy**: Work and personal projects stay isolated
164
+
165
+ ### Upgrading from Earlier Versions?
166
+
167
+ Your existing conversations remain searchable. The only change is that searches now default to your current project. To get the old behavior, simply ask to "search all projects".
168
+
169
+ See [Project-Scoped Search Guide](docs/project-scoped-search.md) for detailed examples and advanced usage.
170
+
126
171
  ## Memory Decay
127
172
 
128
173
  Recent conversations matter more. Old ones fade. Like your brain, but reliable.
@@ -192,6 +237,11 @@ Both embedding options work well. Local mode uses FastEmbed for privacy and offl
192
237
  - [GitHub Issues](https://github.com/ramakay/claude-self-reflect/issues)
193
238
  - [Discussions](https://github.com/ramakay/claude-self-reflect/discussions)
194
239
 
240
+ ## Latest Updates
241
+
242
+ - 📢 [v2.4.x Announcement](https://github.com/ramakay/claude-self-reflect/discussions/19) - Major improvements including Docker setup and project-scoped search
243
+ - 💬 [Project-Scoped Search Feedback](https://github.com/ramakay/claude-self-reflect/discussions/17) - Share your experience with the breaking change
244
+
195
245
  ## Contributing
196
246
 
197
247
  See our [Contributing Guide](CONTRIBUTING.md) for development setup and guidelines.
@@ -7,6 +7,7 @@ from typing import Any, Optional, List, Dict, Union
7
7
  from datetime import datetime
8
8
  import json
9
9
  import numpy as np
10
+ import hashlib
10
11
 
11
12
  from fastmcp import FastMCP, Context
12
13
  from pydantic import BaseModel, Field
@@ -149,7 +150,8 @@ async def reflect_on_past(
149
150
  query: str = Field(description="The search query to find semantically similar conversations"),
150
151
  limit: int = Field(default=5, description="Maximum number of results to return"),
151
152
  min_score: float = Field(default=0.7, description="Minimum similarity score (0-1)"),
152
- use_decay: Union[int, str] = Field(default=-1, description="Apply time-based decay: 1=enable, 0=disable, -1=use environment default (accepts int or str)")
153
+ use_decay: Union[int, str] = Field(default=-1, description="Apply time-based decay: 1=enable, 0=disable, -1=use environment default (accepts int or str)"),
154
+ project: Optional[str] = Field(default=None, description="Search specific project only. If not provided, searches current project based on working directory. Use 'all' to search across all projects.")
153
155
  ) -> str:
154
156
  """Search for relevant past conversations using semantic search with optional time decay."""
155
157
 
@@ -167,7 +169,37 @@ async def reflect_on_past(
167
169
  else ENABLE_MEMORY_DECAY # -1 or any other value
168
170
  )
169
171
 
172
+ # Determine project scope
173
+ target_project = project
174
+ if project is None:
175
+ # Try to detect current project from working directory
176
+ cwd = os.getcwd()
177
+ # Extract project name from path (e.g., /Users/.../projects/project-name)
178
+ path_parts = Path(cwd).parts
179
+ if 'projects' in path_parts:
180
+ idx = path_parts.index('projects')
181
+ if idx + 1 < len(path_parts):
182
+ target_project = path_parts[idx + 1]
183
+ elif '.claude' in path_parts:
184
+ # If we're in a .claude directory, go up to find project
185
+ for i, part in enumerate(path_parts):
186
+ if part == '.claude' and i > 0:
187
+ target_project = path_parts[i - 1]
188
+ break
189
+
190
+ # If still no project detected, use the last directory name
191
+ if target_project is None:
192
+ target_project = Path(cwd).name
193
+
194
+ # For project matching, we need to handle the dash-encoded format
195
+ # Convert folder name to the format used in stored data
196
+ if target_project != 'all':
197
+ # The stored format uses full path with dashes, so we need to construct it
198
+ # For now, let's try to match based on the end of the project name
199
+ pass # We'll handle this differently in the filtering logic
200
+
170
201
  await ctx.debug(f"Searching for: {query}")
202
+ await ctx.debug(f"Project scope: {target_project if target_project != 'all' else 'all projects'}")
171
203
  await ctx.debug(f"Decay enabled: {should_use_decay}")
172
204
  await ctx.debug(f"Native decay mode: {USE_NATIVE_DECAY}")
173
205
  await ctx.debug(f"ENABLE_MEMORY_DECAY env: {ENABLE_MEMORY_DECAY}")
@@ -182,13 +214,34 @@ async def reflect_on_past(
182
214
  if not all_collections:
183
215
  return "No conversation collections found. Please import conversations first."
184
216
 
185
- await ctx.debug(f"Searching across {len(all_collections)} collections")
217
+ # Filter collections by project if not searching all
218
+ project_collections = [] # Define at this scope for later use
219
+ if target_project != 'all':
220
+ # Generate the collection name pattern for this project
221
+ project_hash = hashlib.md5(target_project.encode()).hexdigest()[:8]
222
+ project_collections = [
223
+ c for c in all_collections
224
+ if c.startswith(f"conv_{project_hash}_")
225
+ ]
226
+
227
+ if not project_collections:
228
+ # Try to find collections with project metadata
229
+ # Fall back to searching all collections but filtering by project metadata
230
+ await ctx.debug(f"No collections found for project hash {project_hash}, will filter by metadata")
231
+ collections_to_search = all_collections
232
+ else:
233
+ await ctx.debug(f"Found {len(project_collections)} collections for project {target_project}")
234
+ collections_to_search = project_collections
235
+ else:
236
+ collections_to_search = all_collections
237
+
238
+ await ctx.debug(f"Searching across {len(collections_to_search)} collections")
186
239
  await ctx.debug(f"Using {'local' if PREFER_LOCAL_EMBEDDINGS or not voyage_client else 'Voyage AI'} embeddings")
187
240
 
188
241
  all_results = []
189
242
 
190
243
  # Search each collection
191
- for collection_name in all_collections:
244
+ for collection_name in collections_to_search:
192
245
  try:
193
246
  if should_use_decay and USE_NATIVE_DECAY and NATIVE_DECAY_AVAILABLE:
194
247
  # Use native Qdrant decay with newer API
@@ -285,13 +338,23 @@ async def reflect_on_past(
285
338
  raw_timestamp = point.payload.get('timestamp', datetime.now().isoformat())
286
339
  clean_timestamp = raw_timestamp.replace('Z', '+00:00') if raw_timestamp.endswith('Z') else raw_timestamp
287
340
 
341
+ # Check project filter if we're searching all collections but want specific project
342
+ point_project = point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', ''))
343
+
344
+ # Handle project matching - check if the target project name appears at the end of the stored project path
345
+ if target_project != 'all' and not project_collections:
346
+ # The stored project name is like "-Users-ramakrishnanannaswamy-projects-ShopifyMCPMockShop"
347
+ # We want to match just "ShopifyMCPMockShop"
348
+ if not point_project.endswith(f"-{target_project}") and point_project != target_project:
349
+ continue # Skip results from other projects
350
+
288
351
  all_results.append(SearchResult(
289
352
  id=str(point.id),
290
353
  score=point.score, # Score already includes decay
291
354
  timestamp=clean_timestamp,
292
355
  role=point.payload.get('start_role', point.payload.get('role', 'unknown')),
293
356
  excerpt=(point.payload.get('text', '')[:500] + '...'),
294
- project_name=point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', '')),
357
+ project_name=point_project,
295
358
  conversation_id=point.payload.get('conversation_id'),
296
359
  collection_name=collection_name
297
360
  ))
@@ -350,13 +413,23 @@ async def reflect_on_past(
350
413
  raw_timestamp = point.payload.get('timestamp', datetime.now().isoformat())
351
414
  clean_timestamp = raw_timestamp.replace('Z', '+00:00') if raw_timestamp.endswith('Z') else raw_timestamp
352
415
 
416
+ # Check project filter if we're searching all collections but want specific project
417
+ point_project = point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', ''))
418
+
419
+ # Handle project matching - check if the target project name appears at the end of the stored project path
420
+ if target_project != 'all' and not project_collections:
421
+ # The stored project name is like "-Users-ramakrishnanannaswamy-projects-ShopifyMCPMockShop"
422
+ # We want to match just "ShopifyMCPMockShop"
423
+ if not point_project.endswith(f"-{target_project}") and point_project != target_project:
424
+ continue # Skip results from other projects
425
+
353
426
  all_results.append(SearchResult(
354
427
  id=str(point.id),
355
428
  score=adjusted_score, # Use adjusted score
356
429
  timestamp=clean_timestamp,
357
430
  role=point.payload.get('start_role', point.payload.get('role', 'unknown')),
358
431
  excerpt=(point.payload.get('text', '')[:500] + '...'),
359
- project_name=point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', '')),
432
+ project_name=point_project,
360
433
  conversation_id=point.payload.get('conversation_id'),
361
434
  collection_name=collection_name
362
435
  ))
@@ -375,13 +448,23 @@ async def reflect_on_past(
375
448
  raw_timestamp = point.payload.get('timestamp', datetime.now().isoformat())
376
449
  clean_timestamp = raw_timestamp.replace('Z', '+00:00') if raw_timestamp.endswith('Z') else raw_timestamp
377
450
 
451
+ # Check project filter if we're searching all collections but want specific project
452
+ point_project = point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', ''))
453
+
454
+ # Handle project matching - check if the target project name appears at the end of the stored project path
455
+ if target_project != 'all' and not project_collections:
456
+ # The stored project name is like "-Users-ramakrishnanannaswamy-projects-ShopifyMCPMockShop"
457
+ # We want to match just "ShopifyMCPMockShop"
458
+ if not point_project.endswith(f"-{target_project}") and point_project != target_project:
459
+ continue # Skip results from other projects
460
+
378
461
  all_results.append(SearchResult(
379
462
  id=str(point.id),
380
463
  score=point.score,
381
464
  timestamp=clean_timestamp,
382
465
  role=point.payload.get('start_role', point.payload.get('role', 'unknown')),
383
466
  excerpt=(point.payload.get('text', '')[:500] + '...'),
384
- project_name=point.payload.get('project', collection_name.replace('conv_', '').replace('_voyage', '').replace('_local', '')),
467
+ project_name=point_project,
385
468
  conversation_id=point.payload.get('conversation_id'),
386
469
  collection_name=collection_name
387
470
  ))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-self-reflect",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "Give Claude perfect memory of all your conversations - Installation wizard for Python MCP server",
5
5
  "keywords": [
6
6
  "claude",