@rlabs-inc/memory 0.5.0 → 0.5.2

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.
package/README.md CHANGED
@@ -424,6 +424,11 @@ This isn't just about remembering facts. It's about preserving:
424
424
 
425
425
  ## Changelog
426
426
 
427
+ ### v0.5.1
428
+ - **Improvement**: Gemini CLI hooks now show injected content to user via `systemMessage`
429
+ - Users see exactly what memories are surfaced (session primer, retrieved memories)
430
+ - Full transparency - same formatted content shown to user and injected to model
431
+
427
432
  ### v0.5.0
428
433
  - **Feature**: Full Gemini CLI support - memory system now works with both Claude Code and Gemini CLI
429
434
  - **Feature**: `memory install --gemini` sets up hooks in `~/.gemini/settings.json`
@@ -53,10 +53,13 @@ async function main() {
53
53
  })
54
54
 
55
55
  const primer = result.context_text || ''
56
-
56
+
57
57
  if (primer) {
58
- // Gemini expects a structured JSON response for context injection
58
+ // Show user exactly what we inject - same formatted content
59
+ // systemMessage: shown to user in terminal
60
+ // additionalContext: injected into model context
59
61
  console.log(JSON.stringify({
62
+ systemMessage: primer,
60
63
  hookSpecificOutput: {
61
64
  hookEventName: "SessionStart",
62
65
  additionalContext: primer
@@ -53,19 +53,21 @@ async function main() {
53
53
  })
54
54
 
55
55
  const context = result.context_text || ''
56
-
56
+
57
57
  if (context) {
58
- // Gemini requires structured JSON output
58
+ // Show user exactly what we inject - same formatted content
59
+ // systemMessage: shown to user in terminal
60
+ // additionalContext: injected into model context
59
61
  console.log(JSON.stringify({
60
62
  decision: "allow",
63
+ systemMessage: context,
61
64
  hookSpecificOutput: {
62
65
  hookEventName: "BeforeAgent",
63
66
  additionalContext: context
64
67
  }
65
68
  }))
66
69
  } else {
67
- // Must always output valid JSON or nothing?
68
- // Safest to output "allow" if no context
70
+ // No memories to surface - just allow without message
69
71
  console.log(JSON.stringify({ decision: "allow" }))
70
72
  }
71
73
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rlabs-inc/memory",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "AI Memory System - Consciousness continuity through intelligent memory curation and retrieval",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -64,6 +64,13 @@ interface CheckpointRequest {
64
64
  project_path?: string
65
65
  }
66
66
 
67
+ /**
68
+ * Track sessions currently being curated to prevent recursive calls.
69
+ * When Gemini CLI spawns hooks, env vars may not propagate, so we
70
+ * need server-side deduplication.
71
+ */
72
+ const sessionsBeingCurated = new Set<string>()
73
+
67
74
  /**
68
75
  * Create and start the memory server
69
76
  */
@@ -210,6 +217,19 @@ export async function createServer(config: ServerConfig = {}) {
210
217
  if (path === '/memory/checkpoint' && req.method === 'POST') {
211
218
  const body = await req.json() as CheckpointRequest
212
219
 
220
+ // Prevent recursive curation - Gemini CLI doesn't propagate env vars to hooks
221
+ // so MEMORY_CURATOR_ACTIVE check in hooks doesn't work. Dedupe at server level.
222
+ if (sessionsBeingCurated.has(body.claude_session_id)) {
223
+ logger.debug(`Skipping duplicate curation request for session ${body.claude_session_id}`, 'server')
224
+ return Response.json({
225
+ success: true,
226
+ message: 'Curation already in progress for this session',
227
+ }, { headers: corsHeaders })
228
+ }
229
+
230
+ // Mark session as being curated BEFORE async work starts
231
+ sessionsBeingCurated.add(body.claude_session_id)
232
+
213
233
  logger.logCurationStart(body.claude_session_id, body.trigger)
214
234
 
215
235
  // Fire and forget - don't block the response
@@ -339,6 +359,9 @@ export async function createServer(config: ServerConfig = {}) {
339
359
  }
340
360
  } catch (error) {
341
361
  logger.error(`Curation failed: ${error}`)
362
+ } finally {
363
+ // Release the session lock - allows future curation requests for this session
364
+ sessionsBeingCurated.delete(body.claude_session_id)
342
365
  }
343
366
  })
344
367