- on_stop_cursor.sh: add loop_count guard to prevent infinite re-entry
- on_stop.sh: drop set -e so stats failure doesn't kill the reminder
- _identity.py: fix fallback stub signatures to match production (accept cwd arg)
- on_pre_compact.py: add missing infer=False on session_state writes
- on_session_start.sh: handle v3 search response format (dict with results key)
- Align all plugin versions to 0.2.1 (Claude Code, Codex, Cursor)
Root cause: .mcp.json required ${MEM0_API_KEY} shell env var which
OAuth flow never populates — MCP server never started, only auth
stubs were exposed.
Fix: switch .mcp.json to ${user_config.MEM0_API_KEY} so Claude Code
reads the key from plugin userConfig (system keychain). Add
resolve_api_key() fallback chain (MEM0_API_KEY -> CLAUDE_PLUGIN_OPTION_MEM0_API_KEY)
to all hook scripts. Update onboard skill and setup_coding_categories.py
to handle keychain-only users. Add 3 tests for key resolution.