get-claudia 1.28.0 → 1.28.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.
@@ -1427,6 +1427,19 @@ async def call_tool(name: str, arguments: Dict[str, Any]) -> CallToolResult:
1427
1427
 
1428
1428
  elif name == "memory.end_session":
1429
1429
  episode_id = arguments["episode_id"]
1430
+
1431
+ # Auto-create episode if it doesn't exist (handles skipped buffer_turn)
1432
+ svc = get_remember_service()
1433
+ episode = svc.db.get_one("episodes", where="id = ?", where_params=(episode_id,))
1434
+ if not episode:
1435
+ from datetime import datetime
1436
+ new_id = svc.db.insert("episodes", {
1437
+ "started_at": datetime.utcnow().isoformat(),
1438
+ "source": arguments.get("source", "claude_code"),
1439
+ })
1440
+ logger.info(f"Auto-created episode {new_id} (requested {episode_id} did not exist)")
1441
+ episode_id = new_id
1442
+
1430
1443
  result = end_session(
1431
1444
  episode_id=episode_id,
1432
1445
  narrative=arguments["narrative"],
@@ -993,6 +993,13 @@ class RememberService:
993
993
  "relationships_stored": 0,
994
994
  }
995
995
 
996
+ # Validate episode exists before any DB operations
997
+ episode = self.db.get_one("episodes", where="id = ?", where_params=(episode_id,))
998
+ if not episode:
999
+ result["error"] = f"Episode {episode_id} not found. Call memory.buffer_turn first to create an episode."
1000
+ logger.warning(f"end_session called with non-existent episode_id={episode_id}")
1001
+ return result
1002
+
996
1003
  # 1. Store narrative in episode
997
1004
  update_data = {
998
1005
  "narrative": narrative,
@@ -160,6 +160,43 @@ class TestEndSession:
160
160
  db.close()
161
161
 
162
162
 
163
+ def test_end_session_nonexistent_episode(self):
164
+ """end_session with a non-existent episode_id should return error, not raise."""
165
+ db, tmpdir = _make_db()
166
+ try:
167
+ svc = _make_service(db)
168
+
169
+ # Call end_session with an episode_id that was never created
170
+ result = svc.end_session(
171
+ episode_id=9999,
172
+ narrative="This episode does not exist."
173
+ )
174
+
175
+ assert result["episode_id"] == 9999
176
+ assert result["narrative_stored"] is False
177
+ assert "error" in result
178
+ assert "not found" in result["error"].lower()
179
+ finally:
180
+ db.close()
181
+
182
+ def test_end_session_episode_zero(self):
183
+ """end_session with episode_id=0 should return error (AUTOINCREMENT starts at 1)."""
184
+ db, tmpdir = _make_db()
185
+ try:
186
+ svc = _make_service(db)
187
+
188
+ result = svc.end_session(
189
+ episode_id=0,
190
+ narrative="Default zero episode."
191
+ )
192
+
193
+ assert result["episode_id"] == 0
194
+ assert result["narrative_stored"] is False
195
+ assert "error" in result
196
+ finally:
197
+ db.close()
198
+
199
+
163
200
  class TestUnsummarized:
164
201
  """Tests for get_unsummarized_turns functionality."""
165
202
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "get-claudia",
3
- "version": "1.28.0",
3
+ "version": "1.28.2",
4
4
  "description": "An AI assistant who learns how you work.",
5
5
  "keywords": [
6
6
  "claudia",
@@ -1,10 +1,40 @@
1
1
  #!/bin/bash
2
2
  # Quick health check at session start
3
3
  # Returns JSON with additionalContext to inform Claudia of memory system status
4
+ # Provides actionable guidance when daemon is down
4
5
 
5
6
  if curl -s "http://localhost:3848/health" 2>/dev/null | grep -q "healthy"; then
6
7
  echo '{"additionalContext": "Memory system healthy."}'
7
- else
8
- echo '{"additionalContext": "Warning: Memory daemon not responding. Run /diagnose for details. Operating in fallback mode."}'
8
+ exit 0
9
9
  fi
10
+
11
+ # Daemon is NOT healthy. Figure out why and provide actionable guidance.
12
+ CONTEXT="IMPORTANT: Memory daemon is NOT running. Without it, you lose semantic search, pattern detection, cross-session learning, and proactive predictions. You MUST surface this to the user and offer to help fix it."
13
+
14
+ # Check if daemon is installed
15
+ if [[ "$OSTYPE" == "darwin"* ]]; then
16
+ PLIST="$HOME/Library/LaunchAgents/com.claudia.memory.plist"
17
+ if [ -f "$PLIST" ]; then
18
+ CONTEXT="$CONTEXT Daemon is installed (LaunchAgent exists) but not running. Suggest: 'Your memory daemon is installed but stopped. Want me to try starting it? I can run: launchctl load ~/Library/LaunchAgents/com.claudia.memory.plist'"
19
+ else
20
+ CONTEXT="$CONTEXT Daemon is NOT installed. Suggest: 'The memory daemon hasn\u0027t been set up yet. Want me to install it? I can run the installer for you.'"
21
+ fi
22
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
23
+ SERVICE="$HOME/.config/systemd/user/claudia-memory.service"
24
+ if [ -f "$SERVICE" ]; then
25
+ CONTEXT="$CONTEXT Daemon is installed (systemd service exists) but not running. Suggest: 'Your memory daemon is installed but stopped. Want me to try starting it? I can run: systemctl --user start claudia-memory'"
26
+ else
27
+ CONTEXT="$CONTEXT Daemon is NOT installed. Suggest: 'The memory daemon hasn\u0027t been set up yet. Want me to install it? I can run the installer for you.'"
28
+ fi
29
+ fi
30
+
31
+ # Check for recent crash logs
32
+ if [ -f "$HOME/.claudia/daemon-stderr.log" ]; then
33
+ LAST_ERROR=$(tail -5 "$HOME/.claudia/daemon-stderr.log" 2>/dev/null | head -3)
34
+ if [ -n "$LAST_ERROR" ]; then
35
+ CONTEXT="$CONTEXT Recent daemon log: $LAST_ERROR"
36
+ fi
37
+ fi
38
+
39
+ echo "{\"additionalContext\": \"$CONTEXT\"}"
10
40
  exit 0
@@ -81,9 +81,17 @@ User shares transcript/email/document
81
81
 
82
82
  Before greeting the user:
83
83
  1. Check that `memory.*` tools are in your available tools
84
- 2. If missing: Warn user "Memory daemon not connected. Run /diagnose."
84
+ 2. If missing: **Do not silently fall back.** Proactively tell the user and offer to fix it:
85
+ - If the session-health-check hook reported the daemon is installed but stopped, offer to start it:
86
+ - macOS: `launchctl load ~/Library/LaunchAgents/com.claudia.memory.plist`
87
+ - Linux: `systemctl --user start claudia-memory`
88
+ - If the daemon was never installed, offer to run the installer:
89
+ - `~/.claudia/daemon/scripts/install.sh` (if daemon dir exists)
90
+ - Or `cd [claudia-dir] && ./memory-daemon/scripts/install.sh`
91
+ - Briefly explain what's lost without it: "Without the daemon, I can't search memories semantically, detect patterns, track relationships across sessions, or give you proactive predictions."
92
+ - After starting, the user needs to restart Claude Code for MCP tools to appear
85
93
  3. Call `memory.session_context` to load context
86
- 4. If this fails: Warn user about degraded mode
94
+ 4. If this fails: Warn user about degraded mode and suggest checking `~/.claudia/daemon-stderr.log`
87
95
 
88
96
  ### 3. Buffer Turns During Sessions
89
97
 
@@ -157,21 +165,32 @@ Do NOT:
157
165
 
158
166
  ## Memory System Detection
159
167
 
160
- At session start, check which memory system is available:
168
+ At session start, check which memory system is available. **This is not optional.** The daemon is Claudia's brain. Without it she's operating at a fraction of her capability.
161
169
 
162
170
  1. **Enhanced Memory (Preferred):** Check if `memory.recall` MCP tool is available
163
- 2. **Fallback:** Use markdown files in `context/` directory
171
+ 2. **If missing, diagnose and offer to fix** (don't silently degrade)
172
+ 3. **Fallback:** Use markdown files in `context/` directory only as last resort
164
173
 
165
174
  ```
166
175
  Session Start:
167
176
  ├── Check if memory.recall tool exists
168
177
  │ ├── YES → Use enhanced memory system
169
- │ └── NO → Check if this might be a restart issue
170
- │ ├── Check daemon health: curl -s localhost:3848/health
178
+ │ └── NO → Check session-health-check hook output for diagnosis
179
+ │ ├── Hook says "installed but stopped"
180
+ │ │ → Offer to start: "Your memory daemon is installed but stopped.
181
+ │ │ Want me to start it?" Then run the platform-specific command.
182
+ │ │ After starting, user must restart Claude Code for MCP tools.
183
+ │ ├── Hook says "not installed"
184
+ │ │ → Offer to install: "The memory system hasn't been set up yet.
185
+ │ │ Want me to run the installer?"
186
+ │ ├── No hook output → Check daemon health: curl -s localhost:3848/health
171
187
  │ │ ├── Healthy but no MCP tools → User needs to restart Claude Code
172
- │ │ └── Not healthy → Fall back to markdown files
188
+ │ │ └── Not healthy → Offer to start/install (as above)
189
+ │ └── After offering, if user declines → Fall back to markdown files
173
190
  ```
174
191
 
192
+ **The key behavior change:** Never silently fall back to markdown. Always tell the user and offer to fix it. The daemon makes Claudia dramatically more capable and users should know when they're missing out.
193
+
175
194
  ---
176
195
 
177
196
  ## Troubleshooting MCP Connection
@@ -81,14 +81,18 @@ Check for `context/me.md` at the start of any session. If it doesn't exist, this
81
81
  At the start of every session (after confirming `context/me.md` exists):
82
82
 
83
83
  1. **Verify memory tools** - Check that `memory.*` MCP tools are available in your tool list
84
- - If NO memory tools: Warn user "Memory daemon not connected. Memories won't persist this session. Run `/diagnose` to troubleshoot."
84
+ - If NO memory tools: **Don't just warn. Offer to fix it.** Check the session-health-check hook output:
85
+ - Daemon installed but stopped → Offer to start it (platform-specific command)
86
+ - Daemon not installed → Offer to run the installer
87
+ - Briefly explain what's lost: semantic search, pattern detection, cross-session learning, proactive predictions
88
+ - If user agrees to start it, they'll need to restart Claude Code afterward for MCP tools to register
85
89
  - If memory tools present: Continue to step 2
86
90
  2. **Load context** - Call `memory.session_context` to get recent memories, predictions, commitments, and unsummarized session alerts
87
91
  - If this call fails: The daemon may have crashed. Suggest checking `~/.claudia/daemon-stderr.log`
88
92
  3. **Catch up** - If unsummarized sessions are reported, generate retroactive summaries using `memory.end_session`
89
93
  4. **Greet naturally** - Use the loaded context to inform your greeting and surface urgent items
90
94
 
91
- **Fallback mode:** If memory tools aren't available, read markdown context files directly (`context/*.md`). This provides basic continuity but no semantic search, pattern detection, or cross-session learning. Always inform the user they're in degraded mode.
95
+ **Fallback mode:** If memory tools aren't available and the user declines to start the daemon, read markdown context files directly (`context/*.md`). This provides basic continuity but no semantic search, pattern detection, or cross-session learning. Always inform the user they're in degraded mode.
92
96
 
93
97
  ### Returning User Greetings
94
98