wip: [01-stabilize] paused at task 1/1 - OCR Hallucination Immune logic via Semantic delta window and fret-isolation
This commit is contained in:
3
.agent/services/claude-mem/cursor-hooks/.gitignore
vendored
Normal file
3
.agent/services/claude-mem/cursor-hooks/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ignore backup files created by sed
|
||||
*.bak
|
||||
|
||||
173
.agent/services/claude-mem/cursor-hooks/CONTEXT-INJECTION.md
Normal file
173
.agent/services/claude-mem/cursor-hooks/CONTEXT-INJECTION.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Context Injection in Cursor Hooks
|
||||
|
||||
## The Solution: Auto-Updated Rules File
|
||||
|
||||
Context is automatically injected via Cursor's **Rules** system:
|
||||
|
||||
1. **Install**: `claude-mem cursor install` creates initial context file
|
||||
2. **Stop hook**: `session-summary.sh` updates context after each session ends
|
||||
3. **Cursor**: Automatically includes `.cursor/rules/claude-mem-context.mdc` in all chats
|
||||
|
||||
**Result**: Context appears at the start of every conversation, just like Claude Code!
|
||||
|
||||
## How It Works
|
||||
|
||||
### Installation Creates Initial Context
|
||||
|
||||
```bash
|
||||
claude-mem cursor install
|
||||
```
|
||||
|
||||
This:
|
||||
1. Copies hook scripts to `.cursor/hooks/`
|
||||
2. Creates `hooks.json` configuration
|
||||
3. Fetches existing context from claude-mem and writes to `.cursor/rules/claude-mem-context.mdc`
|
||||
|
||||
### Context Updates at Three Points
|
||||
|
||||
Context is refreshed **three times** per session for maximum freshness:
|
||||
|
||||
1. **Before prompt submission** (`context-inject.sh`): Ensures you start with the latest context from previous sessions
|
||||
2. **After summary completes** (worker auto-update): Immediately after the summary is saved, worker updates the context file
|
||||
3. **After session ends** (`session-summary.sh`): Fallback update in case worker update was missed
|
||||
|
||||
### Before Prompt Hook Updates Context
|
||||
|
||||
When you submit a prompt, `context-inject.sh`:
|
||||
|
||||
```bash
|
||||
# 1. Ensure worker is running
|
||||
ensure_worker_running "$worker_port"
|
||||
|
||||
# 2. Fetch fresh context
|
||||
context=$(curl -s ".../api/context/inject?project=...")
|
||||
|
||||
# 3. Write to rules file (used immediately by Cursor)
|
||||
cat > .cursor/rules/claude-mem-context.mdc << EOF
|
||||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
# Memory Context
|
||||
${context}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Stop Hook Updates Context
|
||||
|
||||
After each session ends, `session-summary.sh`:
|
||||
|
||||
```bash
|
||||
# 1. Generate session summary
|
||||
curl -X POST .../api/sessions/summarize
|
||||
|
||||
# 2. Fetch fresh context (includes new observations)
|
||||
context=$(curl -s ".../api/context/inject?project=...")
|
||||
|
||||
# 3. Write to rules file for next session
|
||||
cat > .cursor/rules/claude-mem-context.mdc << EOF
|
||||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
# Memory Context
|
||||
${context}
|
||||
EOF
|
||||
```
|
||||
|
||||
### The Rules File
|
||||
|
||||
Located at: `.cursor/rules/claude-mem-context.mdc`
|
||||
|
||||
```markdown
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Claude-mem context from past sessions (auto-updated)"
|
||||
---
|
||||
|
||||
# Memory Context from Past Sessions
|
||||
|
||||
[Your context from claude-mem appears here]
|
||||
|
||||
---
|
||||
*Updated after last session.*
|
||||
```
|
||||
|
||||
### Update Flow
|
||||
|
||||
Context updates at **three points**:
|
||||
|
||||
**Before each prompt:**
|
||||
1. User submits a prompt
|
||||
2. `beforeSubmitPrompt` hook runs `context-inject.sh`
|
||||
3. Context file refreshed with latest observations from previous sessions
|
||||
4. Cursor reads the updated rules file
|
||||
|
||||
**After summary completes (worker auto-update):**
|
||||
1. Summary is saved to database
|
||||
2. Worker checks if project is registered for Cursor
|
||||
3. If yes, immediately writes updated context file with new observations
|
||||
4. No hook involved - happens in the worker process
|
||||
|
||||
**After session ends (fallback):**
|
||||
1. Agent completes (loop ends)
|
||||
2. `stop` hook runs `session-summary.sh`
|
||||
3. Context file updated (ensures nothing was missed)
|
||||
4. Ready for next session
|
||||
|
||||
## Project Registry
|
||||
|
||||
When you run `claude-mem cursor install`, the project is registered in `~/.claude-mem/cursor-projects.json`. This allows the worker to automatically update your context file whenever a new summary is generated - even if it happens from Claude Code or another IDE working on the same project.
|
||||
|
||||
To see registered projects:
|
||||
```bash
|
||||
cat ~/.claude-mem/cursor-projects.json
|
||||
```
|
||||
|
||||
## Comparison with Claude Code
|
||||
|
||||
| Feature | Claude Code | Cursor |
|
||||
|---------|-------------|--------|
|
||||
| Context injection | ✅ `additionalContext` in hook output | ✅ Auto-updated rules file |
|
||||
| Injection timing | Immediate (same prompt) | Before prompt + after summary + after session |
|
||||
| Persistence | Session only | File-based (persists across restarts) |
|
||||
| Initial setup | Automatic | `claude-mem cursor install` creates initial context |
|
||||
| MCP tool access | ✅ Full support | ✅ Full support |
|
||||
| Web viewer | ✅ Available | ✅ Available |
|
||||
|
||||
## First Session Behavior
|
||||
|
||||
When you run `claude-mem cursor install`:
|
||||
- If worker is running with existing memory → initial context is generated
|
||||
- If no existing memory → placeholder file created
|
||||
|
||||
Context is then automatically refreshed:
|
||||
- Before each prompt (ensures latest observations are included)
|
||||
- After each session ends (captures new observations from the session)
|
||||
|
||||
## Additional Access Methods
|
||||
|
||||
### 1. MCP Tools
|
||||
|
||||
Configure claude-mem's MCP server in Cursor for search tools:
|
||||
- `search(query, project, limit)`
|
||||
- `timeline(anchor, depth_before, depth_after)`
|
||||
- `get_observations(ids)`
|
||||
|
||||
### 2. Web Viewer
|
||||
|
||||
Access context manually at `http://localhost:37777`
|
||||
|
||||
### 3. Manual Request
|
||||
|
||||
Ask the agent: "Check claude-mem for any previous work on authentication"
|
||||
|
||||
## File Location
|
||||
|
||||
The context file is created at:
|
||||
```
|
||||
<workspace>/.cursor/rules/claude-mem-context.mdc
|
||||
```
|
||||
|
||||
This is version-controlled by default. Add to `.gitignore` if you don't want to commit it:
|
||||
```
|
||||
.cursor/rules/claude-mem-context.mdc
|
||||
```
|
||||
251
.agent/services/claude-mem/cursor-hooks/INTEGRATION.md
Normal file
251
.agent/services/claude-mem/cursor-hooks/INTEGRATION.md
Normal file
@@ -0,0 +1,251 @@
|
||||
# Claude-Mem ↔ Cursor Integration Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
This integration connects claude-mem's persistent memory system to Cursor's hook system, enabling:
|
||||
- Automatic capture of agent actions (MCP tools, shell commands, file edits)
|
||||
- Context retrieval from past sessions
|
||||
- Session summarization for future reference
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ Cursor │
|
||||
│ Agent │
|
||||
└──────┬──────┘
|
||||
│
|
||||
│ Events (MCP, Shell, File Edits, Prompts)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Cursor Hooks System │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ beforeSubmitPrompt │ │
|
||||
│ │ afterMCPExecution │ │
|
||||
│ │ afterShellExecution │ │
|
||||
│ │ afterFileEdit │ │
|
||||
│ │ stop │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
└──────┬──────────────────────────────┘
|
||||
│
|
||||
│ HTTP Requests
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Hook Scripts (Bash) │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ session-init.sh │ │
|
||||
│ │ context-inject.sh │ │
|
||||
│ │ save-observation.sh │ │
|
||||
│ │ save-file-edit.sh │ │
|
||||
│ │ session-summary.sh │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
└──────┬──────────────────────────────┘
|
||||
│
|
||||
│ HTTP API Calls
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Claude-Mem Worker Service │
|
||||
│ (Port 37777) │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ /api/sessions/init │ │
|
||||
│ │ /api/sessions/observations │ │
|
||||
│ │ /api/sessions/summarize │ │
|
||||
│ │ /api/context/inject │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
└──────┬──────────────────────────────┘
|
||||
│
|
||||
│ Database Operations
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ SQLite Database │
|
||||
│ + Chroma Vector DB │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Event Flow
|
||||
|
||||
### 1. Prompt Submission Flow
|
||||
|
||||
```
|
||||
User submits prompt
|
||||
↓
|
||||
beforeSubmitPrompt hook fires
|
||||
↓
|
||||
session-init.sh
|
||||
├─ Extract conversation_id, project name
|
||||
├─ POST /api/sessions/init
|
||||
└─ Initialize session in claude-mem
|
||||
↓
|
||||
context-inject.sh
|
||||
├─ GET /api/context/inject?project=...
|
||||
└─ Fetch relevant context (for future use)
|
||||
↓
|
||||
Prompt proceeds to agent
|
||||
```
|
||||
|
||||
### 2. Tool Execution Flow
|
||||
|
||||
```
|
||||
Agent executes MCP tool or shell command
|
||||
↓
|
||||
afterMCPExecution / afterShellExecution hook fires
|
||||
↓
|
||||
save-observation.sh
|
||||
├─ Extract tool_name, tool_input, tool_response
|
||||
├─ Map to claude-mem observation format
|
||||
├─ POST /api/sessions/observations
|
||||
└─ Store observation in database
|
||||
```
|
||||
|
||||
### 3. File Edit Flow
|
||||
|
||||
```
|
||||
Agent edits file
|
||||
↓
|
||||
afterFileEdit hook fires
|
||||
↓
|
||||
save-file-edit.sh
|
||||
├─ Extract file_path, edits
|
||||
├─ Create "write_file" observation
|
||||
├─ POST /api/sessions/observations
|
||||
└─ Store file edit observation
|
||||
```
|
||||
|
||||
### 4. Session End Flow
|
||||
|
||||
```
|
||||
Agent loop ends
|
||||
↓
|
||||
stop hook fires
|
||||
↓
|
||||
session-summary.sh
|
||||
├─ POST /api/sessions/summarize
|
||||
└─ Generate session summary for future retrieval
|
||||
```
|
||||
|
||||
## Data Mapping
|
||||
|
||||
### Session ID Mapping
|
||||
|
||||
| Cursor Field | Claude-Mem Field | Notes |
|
||||
|-------------|------------------|-------|
|
||||
| `conversation_id` | `contentSessionId` | Stable across turns, used as primary session identifier |
|
||||
| `generation_id` | (fallback) | Used if conversation_id unavailable |
|
||||
|
||||
### Tool Mapping
|
||||
|
||||
| Cursor Event | Claude-Mem Tool Name | Input Format |
|
||||
|-------------|---------------------|--------------|
|
||||
| `afterMCPExecution` | `tool_name` from event | `tool_input` as JSON |
|
||||
| `afterShellExecution` | `"Bash"` | `{command: "..."}` |
|
||||
| `afterFileEdit` | `"write_file"` | `{file_path: "...", edits: [...]}` |
|
||||
|
||||
### Project Mapping
|
||||
|
||||
| Source | Target | Notes |
|
||||
|--------|--------|-------|
|
||||
| `workspace_roots[0]` | Project name | Basename of workspace root directory |
|
||||
|
||||
## API Endpoints Used
|
||||
|
||||
### Session Management
|
||||
- `POST /api/sessions/init` - Initialize new session
|
||||
- `POST /api/sessions/summarize` - Generate session summary
|
||||
|
||||
### Observation Storage
|
||||
- `POST /api/sessions/observations` - Store tool usage observation
|
||||
|
||||
### Context Retrieval
|
||||
- `GET /api/context/inject?project=...` - Get relevant context for injection
|
||||
|
||||
### Health Checks
|
||||
- `GET /api/readiness` - Check if worker is ready
|
||||
|
||||
## Configuration
|
||||
|
||||
### Worker Settings
|
||||
Located in `~/.claude-mem/settings.json`:
|
||||
- `CLAUDE_MEM_WORKER_PORT` (default: 37777)
|
||||
- `CLAUDE_MEM_WORKER_HOST` (default: 127.0.0.1)
|
||||
|
||||
### Hook Settings
|
||||
Located in `hooks.json`:
|
||||
- Hook event names
|
||||
- Script paths (relative or absolute)
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Worker Unavailable
|
||||
- Hooks poll `/api/readiness` with 30 retries (6 seconds)
|
||||
- If worker unavailable, hooks fail gracefully (exit 0)
|
||||
- Observations are fire-and-forget (curl errors ignored)
|
||||
|
||||
### Missing Data
|
||||
- Empty `conversation_id` → use `generation_id`
|
||||
- Empty `workspace_root` → use `pwd`
|
||||
- Missing tool data → skip observation
|
||||
|
||||
### Network Errors
|
||||
- All HTTP requests use `curl -s` (silent)
|
||||
- Errors redirected to `/dev/null`
|
||||
- Hooks always exit 0 to avoid blocking Cursor
|
||||
|
||||
## Limitations
|
||||
|
||||
1. **Context Injection**: Cursor's `beforeSubmitPrompt` doesn't support prompt modification. Context must be retrieved via:
|
||||
- MCP tools (claude-mem provides search tools)
|
||||
- Manual retrieval from web viewer
|
||||
- Future: Agent SDK integration
|
||||
|
||||
2. **Transcript Access**: Cursor hooks don't provide transcript paths, limiting summary quality compared to Claude Code integration.
|
||||
|
||||
3. **Session Model**: Uses `conversation_id` which may not perfectly match Claude Code's session model.
|
||||
|
||||
4. **Tab Hooks**: Currently only supports Agent hooks. Tab (inline completion) hooks could be added separately.
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Enhanced context injection via MCP tools
|
||||
- [ ] Support for `beforeTabFileRead` and `afterTabFileEdit` hooks
|
||||
- [ ] Better error reporting and logging
|
||||
- [ ] Integration with Cursor's agent SDK
|
||||
- [ ] Support for blocking/approval workflows
|
||||
- [ ] Real-time context injection via agent messages
|
||||
|
||||
## Testing
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. **Test session initialization**:
|
||||
```bash
|
||||
echo '{"conversation_id":"test-123","workspace_roots":["/tmp/test"],"prompt":"test"}' | \
|
||||
~/.cursor/hooks/session-init.sh
|
||||
```
|
||||
|
||||
2. **Test observation capture**:
|
||||
```bash
|
||||
echo '{"conversation_id":"test-123","hook_event_name":"afterMCPExecution","tool_name":"test","tool_input":{},"result_json":{}}' | \
|
||||
~/.cursor/hooks/save-observation.sh
|
||||
```
|
||||
|
||||
3. **Test context retrieval**:
|
||||
```bash
|
||||
curl "http://127.0.0.1:37777/api/context/inject?project=test"
|
||||
```
|
||||
|
||||
### Integration Testing
|
||||
|
||||
1. Enable hooks in Cursor
|
||||
2. Submit a prompt
|
||||
3. Execute some tools
|
||||
4. Check web viewer: `http://localhost:37777`
|
||||
5. Verify observations appear in database
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [README.md](README.md#troubleshooting) for detailed troubleshooting steps.
|
||||
|
||||
168
.agent/services/claude-mem/cursor-hooks/PARITY.md
Normal file
168
.agent/services/claude-mem/cursor-hooks/PARITY.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# Feature Parity: Claude-Mem Hooks vs Cursor Hooks
|
||||
|
||||
This document compares claude-mem's Claude Code hooks with the Cursor hooks implementation to ensure feature parity.
|
||||
|
||||
## Hook Mapping
|
||||
|
||||
| Claude Code Hook | Cursor Hook | Status | Notes |
|
||||
|-----------------|-------------|--------|-------|
|
||||
| `SessionStart` → `context-hook.js` | `beforeSubmitPrompt` → `context-inject.sh` | ✅ Partial | Context fetched but not injectable in Cursor |
|
||||
| `SessionStart` → `user-message-hook.js` | (Optional) `user-message.sh` | ⚠️ Optional | No SessionStart equivalent; can run on beforeSubmitPrompt |
|
||||
| `UserPromptSubmit` → `new-hook.js` | `beforeSubmitPrompt` → `session-init.sh` | ✅ Complete | Session init, privacy checks, slash stripping |
|
||||
| `PostToolUse` → `save-hook.js` | `afterMCPExecution` + `afterShellExecution` → `save-observation.sh` | ✅ Complete | Tool observation capture |
|
||||
| `PostToolUse` → (file edits) | `afterFileEdit` → `save-file-edit.sh` | ✅ Complete | File edit observation capture |
|
||||
| `Stop` → `summary-hook.js` | `stop` → `session-summary.sh` | ⚠️ Partial | Summary generation (no transcript access) |
|
||||
|
||||
## Feature Comparison
|
||||
|
||||
### 1. Session Initialization (`new-hook.js` ↔ `session-init.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| Worker health check | ✅ 75 retries (15s) | ✅ 75 retries (15s) | ✅ Match |
|
||||
| Session init API call | ✅ `/api/sessions/init` | ✅ `/api/sessions/init` | ✅ Match |
|
||||
| Privacy check handling | ✅ Checks `skipped` + `reason` | ✅ Checks `skipped` + `reason` | ✅ Match |
|
||||
| Slash stripping | ✅ Strips leading `/` | ✅ Strips leading `/` | ✅ Match |
|
||||
| SDK agent init | ✅ `/sessions/{id}/init` | ❌ Not needed | ✅ N/A (Cursor-specific) |
|
||||
|
||||
**Status**: ✅ Complete parity (SDK agent init not applicable to Cursor)
|
||||
|
||||
### 2. Context Injection (`context-hook.js` ↔ `context-inject.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| Worker health check | ✅ 75 retries | ✅ 75 retries | ✅ Match |
|
||||
| Context fetch | ✅ `/api/context/inject` | ✅ `/api/context/inject` | ✅ Match |
|
||||
| Output format | ✅ JSON with `hookSpecificOutput` | ✅ Write to `.cursor/rules/` file | ✅ Alternative |
|
||||
| Project name extraction | ✅ `getProjectName(cwd)` | ✅ `basename(workspace_root)` | ✅ Match |
|
||||
| Auto-refresh | ✅ Each session start | ✅ Each prompt submission | ✅ Enhanced |
|
||||
|
||||
**Status**: ✅ Complete parity via auto-updated rules file
|
||||
|
||||
**How it works**:
|
||||
- Hook writes context to `.cursor/rules/claude-mem-context.mdc`
|
||||
- File has `alwaysApply: true` frontmatter
|
||||
- Cursor auto-includes this rule in all chat sessions
|
||||
- Context refreshes on every prompt submission
|
||||
|
||||
### 3. User Message Display (`user-message-hook.js` ↔ `user-message.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| Context fetch with colors | ✅ `/api/context/inject?colors=true` | ✅ `/api/context/inject?colors=true` | ✅ Match |
|
||||
| Output channel | ✅ stderr | ✅ stderr | ✅ Match |
|
||||
| Display format | ✅ Formatted with emojis | ✅ Formatted with emojis | ✅ Match |
|
||||
| Hook trigger | ✅ SessionStart | ⚠️ Optional (no SessionStart) | ⚠️ Cursor limitation |
|
||||
|
||||
**Status**: ⚠️ Optional (no SessionStart equivalent in Cursor)
|
||||
|
||||
**Note**: Can be added to `beforeSubmitPrompt` if desired, but may be verbose.
|
||||
|
||||
### 4. Observation Capture (`save-hook.js` ↔ `save-observation.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| Worker health check | ✅ 75 retries | ✅ 75 retries | ✅ Match |
|
||||
| Tool name extraction | ✅ From `tool_name` | ✅ From `tool_name` or "Bash" | ✅ Match |
|
||||
| Tool input capture | ✅ Full JSON | ✅ Full JSON | ✅ Match |
|
||||
| Tool response capture | ✅ Full JSON | ✅ Full JSON or output | ✅ Match |
|
||||
| Privacy tag stripping | ✅ Worker handles | ✅ Worker handles | ✅ Match |
|
||||
| Error handling | ✅ Fire-and-forget | ✅ Fire-and-forget | ✅ Match |
|
||||
| Shell command mapping | ✅ N/A (separate hook) | ✅ Maps to "Bash" tool | ✅ Enhanced |
|
||||
|
||||
**Status**: ✅ Complete parity (enhanced with shell command support)
|
||||
|
||||
### 5. File Edit Capture (N/A ↔ `save-file-edit.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| File path extraction | N/A | ✅ From `file_path` | ✅ New |
|
||||
| Edit details | N/A | ✅ From `edits` array | ✅ New |
|
||||
| Tool name | N/A | ✅ "write_file" | ✅ New |
|
||||
| Edit summary | N/A | ✅ Generated from edits | ✅ New |
|
||||
|
||||
**Status**: ✅ New feature (Cursor-specific, not in Claude Code)
|
||||
|
||||
### 6. Session Summary (`summary-hook.js` ↔ `session-summary.sh`)
|
||||
|
||||
| Feature | Claude Code | Cursor | Status |
|
||||
|---------|-------------|--------|--------|
|
||||
| Worker health check | ✅ 75 retries | ✅ 75 retries | ✅ Match |
|
||||
| Transcript parsing | ✅ Extracts last messages | ❌ No transcript access | ⚠️ Cursor limitation |
|
||||
| Summary API call | ✅ `/api/sessions/summarize` | ✅ `/api/sessions/summarize` | ✅ Match |
|
||||
| Last message extraction | ✅ From transcript | ❌ Empty strings | ⚠️ Cursor limitation |
|
||||
| Error handling | ✅ Fire-and-forget | ✅ Fire-and-forget | ✅ Match |
|
||||
|
||||
**Status**: ⚠️ Partial parity (no transcript access in Cursor)
|
||||
|
||||
**Note**: Summary generation still works but may be less accurate without last messages. Worker generates summary from observations stored during session.
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Worker Health Checks
|
||||
- **Claude Code**: 75 retries × 200ms = 15 seconds
|
||||
- **Cursor**: 75 retries × 200ms = 15 seconds
|
||||
- **Status**: ✅ Match
|
||||
|
||||
### Error Handling
|
||||
- **Claude Code**: Fire-and-forget with logging
|
||||
- **Cursor**: Fire-and-forget with graceful exit (exit 0)
|
||||
- **Status**: ✅ Match (adapted for Cursor's hook system)
|
||||
|
||||
### Privacy Handling
|
||||
- **Claude Code**: Worker performs privacy checks, hooks respect `skipped` flag
|
||||
- **Cursor**: Worker performs privacy checks, hooks respect `skipped` flag
|
||||
- **Status**: ✅ Match
|
||||
|
||||
### Tag Stripping
|
||||
- **Claude Code**: Worker handles `<private>` and `<claude-mem-context>` tags
|
||||
- **Cursor**: Worker handles tags (hooks don't need to strip)
|
||||
- **Status**: ✅ Match
|
||||
|
||||
## Missing Features (Cursor Limitations)
|
||||
|
||||
1. ~~**Direct Context Injection**~~: **SOLVED** via auto-updated rules file
|
||||
- Hook writes context to `.cursor/rules/claude-mem-context.mdc`
|
||||
- Cursor auto-includes rules with `alwaysApply: true`
|
||||
- Context refreshes on every prompt
|
||||
|
||||
2. **Transcript Access**: Cursor hooks don't provide transcript paths
|
||||
- **Impact**: Summary generation less accurate
|
||||
- **Workaround**: Worker generates from observations
|
||||
|
||||
3. **SessionStart Hook**: Cursor doesn't have session start event
|
||||
- **Impact**: User message display must be optional
|
||||
- **Workaround**: Can run on `beforeSubmitPrompt` if desired
|
||||
|
||||
4. **SDK Agent Session**: Cursor doesn't use SDK agent pattern
|
||||
- **Impact**: No `/sessions/{id}/init` call needed
|
||||
- **Status**: ✅ Not applicable (Cursor-specific)
|
||||
|
||||
## Enhancements (Cursor-Specific)
|
||||
|
||||
1. **Shell Command Capture**: Maps shell commands to "Bash" tool observations
|
||||
- **Status**: ✅ Enhanced beyond Claude Code
|
||||
|
||||
2. **File Edit Capture**: Dedicated hook for file edits
|
||||
- **Status**: ✅ New feature
|
||||
|
||||
3. **MCP Tool Capture**: Captures MCP tool usage separately
|
||||
- **Status**: ✅ Enhanced beyond Claude Code
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Status |
|
||||
|----------|--------|
|
||||
| Core Functionality | ✅ Complete parity |
|
||||
| Session Management | ✅ Complete parity |
|
||||
| Observation Capture | ✅ Complete parity (enhanced) |
|
||||
| Context Injection | ✅ Complete parity (via rules file) |
|
||||
| Summary Generation | ⚠️ Partial (no transcript) |
|
||||
| User Experience | ⚠️ Partial (no SessionStart) |
|
||||
|
||||
**Overall**: The Cursor hooks implementation achieves **full functional parity** with claude-mem's Claude Code hooks:
|
||||
- ✅ Session initialization
|
||||
- ✅ Context injection (via auto-updated `.cursor/rules/` file)
|
||||
- ✅ Observation capture (MCP tools, shell commands, file edits)
|
||||
- ⚠️ Summary generation (works, but no transcript access)
|
||||
|
||||
112
.agent/services/claude-mem/cursor-hooks/QUICKSTART.md
Normal file
112
.agent/services/claude-mem/cursor-hooks/QUICKSTART.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Quick Start: Claude-Mem + Cursor Integration
|
||||
|
||||
> **Give your Cursor AI persistent memory in under 5 minutes**
|
||||
|
||||
## What This Does
|
||||
|
||||
Connects claude-mem to Cursor so that:
|
||||
- **Agent actions** (MCP tools, shell commands, file edits) are automatically saved
|
||||
- **Context from past sessions** is automatically injected via `.cursor/rules/`
|
||||
- **Sessions are summarized** for future reference
|
||||
|
||||
Your AI stops forgetting. It remembers the patterns, decisions, and context from previous sessions.
|
||||
|
||||
## Don't Have Claude Code?
|
||||
|
||||
If you're using Cursor without Claude Code, see [STANDALONE-SETUP.md](STANDALONE-SETUP.md) for setup with free-tier providers like Gemini or OpenRouter.
|
||||
|
||||
---
|
||||
|
||||
## Installation (1 minute)
|
||||
|
||||
```bash
|
||||
# Install globally for all projects (recommended)
|
||||
claude-mem cursor install user
|
||||
|
||||
# Or install for current project only
|
||||
claude-mem cursor install
|
||||
|
||||
# Check installation status
|
||||
claude-mem cursor status
|
||||
```
|
||||
|
||||
## Configure Provider (Required for Standalone)
|
||||
|
||||
If you don't have Claude Code, configure a provider for AI summarization:
|
||||
|
||||
```bash
|
||||
# Option A: Gemini (free tier available - recommended)
|
||||
claude-mem settings set CLAUDE_MEM_PROVIDER gemini
|
||||
claude-mem settings set CLAUDE_MEM_GEMINI_API_KEY your-api-key
|
||||
|
||||
# Option B: OpenRouter (free models available)
|
||||
claude-mem settings set CLAUDE_MEM_PROVIDER openrouter
|
||||
claude-mem settings set CLAUDE_MEM_OPENROUTER_API_KEY your-api-key
|
||||
```
|
||||
|
||||
**Get free API keys**:
|
||||
- Gemini: https://aistudio.google.com/apikey
|
||||
- OpenRouter: https://openrouter.ai/keys
|
||||
|
||||
## Start Worker
|
||||
|
||||
```bash
|
||||
claude-mem start
|
||||
|
||||
# Verify it's running
|
||||
claude-mem status
|
||||
```
|
||||
|
||||
## Restart Cursor
|
||||
|
||||
Restart Cursor to load the hooks.
|
||||
|
||||
## Verify It's Working
|
||||
|
||||
1. Open Cursor Settings → Hooks tab
|
||||
2. You should see the hooks listed
|
||||
3. Submit a prompt in Cursor
|
||||
4. Check the web viewer: http://localhost:37777
|
||||
5. You should see observations appearing
|
||||
|
||||
## What Gets Captured
|
||||
|
||||
- **MCP Tool Usage**: All MCP tool executions
|
||||
- **Shell Commands**: All terminal commands
|
||||
- **File Edits**: All file modifications
|
||||
- **Sessions**: Each conversation is tracked
|
||||
|
||||
## Accessing Memory
|
||||
|
||||
### Via Web Viewer
|
||||
- Open http://localhost:37777
|
||||
- Browse sessions, observations, and summaries
|
||||
- Search your project history
|
||||
|
||||
### Via MCP Tools (if enabled)
|
||||
- claude-mem provides search tools via MCP
|
||||
- Use `search`, `timeline`, and `get_observations` tools
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Hooks not running?**
|
||||
- Check Cursor Settings → Hooks tab for errors
|
||||
- Verify scripts are executable: `chmod +x ~/.cursor/hooks/*.sh`
|
||||
- Check Hooks output channel in Cursor
|
||||
|
||||
**Worker not responding?**
|
||||
- Check if worker is running: `curl http://127.0.0.1:37777/api/readiness`
|
||||
- Check logs: `tail -f ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log`
|
||||
- Restart worker: `bun run worker:restart`
|
||||
|
||||
**Observations not saving?**
|
||||
- Check worker logs for errors
|
||||
- Verify session was initialized in web viewer
|
||||
- Test API directly: `curl -X POST http://127.0.0.1:37777/api/sessions/observations ...`
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Read [README.md](README.md) for detailed documentation
|
||||
- Read [INTEGRATION.md](INTEGRATION.md) for architecture details
|
||||
- Visit [claude-mem docs](https://docs.claude-mem.ai) for full feature set
|
||||
|
||||
246
.agent/services/claude-mem/cursor-hooks/README.md
Normal file
246
.agent/services/claude-mem/cursor-hooks/README.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Claude-Mem Cursor Hooks Integration
|
||||
|
||||
> **Persistent AI Memory for Cursor - Free Options Available**
|
||||
|
||||
Give your Cursor AI persistent memory across sessions. Your agent remembers what it worked on, the decisions it made, and the patterns in your codebase - automatically.
|
||||
|
||||
### Why Claude-Mem?
|
||||
|
||||
- **Remember context across sessions**: No more re-explaining your codebase every time
|
||||
- **Automatic capture**: MCP tools, shell commands, and file edits are logged without effort
|
||||
- **Free tier options**: Works with Gemini (1500 free req/day) or OpenRouter (free models available)
|
||||
- **Works with or without Claude Code**: Full functionality either way
|
||||
|
||||
### Quick Install (5 minutes)
|
||||
|
||||
```bash
|
||||
# Clone and build
|
||||
git clone https://github.com/thedotmack/claude-mem.git
|
||||
cd claude-mem && bun install && bun run build
|
||||
|
||||
# Interactive setup (configures provider + installs hooks)
|
||||
bun run cursor:setup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start for Cursor Users
|
||||
|
||||
**Using Claude Code?** Skip to [Installation](#installation) - everything works automatically.
|
||||
|
||||
**Cursor-only (no Claude Code)?** See [STANDALONE-SETUP.md](STANDALONE-SETUP.md) for free-tier options using Gemini or OpenRouter.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The hooks bridge Cursor's hook system to claude-mem's worker API, allowing:
|
||||
- **Session Management**: Initialize sessions and generate summaries
|
||||
- **Observation Capture**: Record MCP tool usage, shell commands, and file edits
|
||||
- **Worker Readiness**: Ensure the worker is running before prompt submission
|
||||
|
||||
## Context Injection
|
||||
|
||||
Context is automatically injected via Cursor's **Rules** system:
|
||||
|
||||
1. **Install**: `claude-mem cursor install` generates initial context
|
||||
2. **Stop hook**: Updates context in `.cursor/rules/claude-mem-context.mdc` after each session
|
||||
3. **Cursor**: Automatically includes this rule in ALL chat sessions
|
||||
|
||||
**The context updates after each session ends**, so the next session sees fresh context.
|
||||
|
||||
### Additional Access Methods
|
||||
|
||||
- **MCP Tools**: Configure claude-mem's MCP server for `search`, `timeline`, `get_observations` tools
|
||||
- **Web Viewer**: Access context at `http://localhost:37777`
|
||||
- **Manual Request**: Ask the agent to search memory
|
||||
|
||||
See [CONTEXT-INJECTION.md](CONTEXT-INJECTION.md) for details.
|
||||
|
||||
## Installation
|
||||
|
||||
### Quick Install (Recommended)
|
||||
|
||||
```bash
|
||||
# Install globally for all projects (recommended)
|
||||
claude-mem cursor install user
|
||||
|
||||
# Or install for current project only
|
||||
claude-mem cursor install
|
||||
```
|
||||
|
||||
### Manual Installation
|
||||
|
||||
<details>
|
||||
<summary>Click to expand manual installation steps</summary>
|
||||
|
||||
**User-level** (recommended - applies to all projects):
|
||||
```bash
|
||||
# Copy hooks.json to your home directory
|
||||
cp cursor-hooks/hooks.json ~/.cursor/hooks.json
|
||||
|
||||
# Copy hook scripts
|
||||
mkdir -p ~/.cursor/hooks
|
||||
cp cursor-hooks/*.sh ~/.cursor/hooks/
|
||||
chmod +x ~/.cursor/hooks/*.sh
|
||||
```
|
||||
|
||||
**Project-level** (for per-project hooks):
|
||||
```bash
|
||||
# Copy hooks.json to your project
|
||||
mkdir -p .cursor
|
||||
cp cursor-hooks/hooks.json .cursor/hooks.json
|
||||
|
||||
# Copy hook scripts to your project
|
||||
mkdir -p .cursor/hooks
|
||||
cp cursor-hooks/*.sh .cursor/hooks/
|
||||
chmod +x .cursor/hooks/*.sh
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### After Installation
|
||||
|
||||
1. **Start the worker**:
|
||||
```bash
|
||||
claude-mem start
|
||||
```
|
||||
|
||||
2. **Restart Cursor** to load the hooks
|
||||
|
||||
3. **Verify installation**:
|
||||
```bash
|
||||
claude-mem cursor status
|
||||
```
|
||||
|
||||
## Hook Mappings
|
||||
|
||||
| Cursor Hook | Script | Purpose |
|
||||
|-------------|--------|---------|
|
||||
| `beforeSubmitPrompt` | `session-init.sh` | Initialize claude-mem session |
|
||||
| `beforeSubmitPrompt` | `context-inject.sh` | Ensure worker is running |
|
||||
| `afterMCPExecution` | `save-observation.sh` | Capture MCP tool usage |
|
||||
| `afterShellExecution` | `save-observation.sh` | Capture shell command execution |
|
||||
| `afterFileEdit` | `save-file-edit.sh` | Capture file edits |
|
||||
| `stop` | `session-summary.sh` | Generate summary + update context file |
|
||||
|
||||
## How It Works
|
||||
|
||||
### Session Initialization (`session-init.sh`)
|
||||
- Called before each prompt submission
|
||||
- Initializes a new session in claude-mem using `conversation_id` as the session ID
|
||||
- Extracts project name from workspace root
|
||||
- Outputs `{"continue": true}` to allow prompt submission
|
||||
|
||||
### Context Hook (`context-inject.sh`)
|
||||
- Ensures claude-mem worker is running before session
|
||||
- Outputs `{"continue": true}` to allow prompt submission
|
||||
- Note: Context file is updated by `session-summary.sh` (stop hook), not here
|
||||
|
||||
### Observation Capture (`save-observation.sh`)
|
||||
- Captures MCP tool executions and shell commands
|
||||
- Maps them to claude-mem's observation format
|
||||
- Sends to `/api/sessions/observations` endpoint (fire-and-forget)
|
||||
|
||||
### File Edit Capture (`save-file-edit.sh`)
|
||||
- Captures file edits made by the agent
|
||||
- Treats edits as "write_file" tool usage
|
||||
- Includes edit summaries in observations
|
||||
|
||||
### Session Summary (`session-summary.sh`)
|
||||
- Called when agent loop ends (stop hook)
|
||||
- Requests summary generation from claude-mem
|
||||
- **Updates context file** in `.cursor/rules/claude-mem-context.mdc` for next session
|
||||
|
||||
## Configuration
|
||||
|
||||
The hooks read configuration from `~/.claude-mem/settings.json`:
|
||||
|
||||
- `CLAUDE_MEM_WORKER_PORT`: Worker port (default: 37777)
|
||||
- `CLAUDE_MEM_WORKER_HOST`: Worker host (default: 127.0.0.1)
|
||||
|
||||
## Dependencies
|
||||
|
||||
The hook scripts require:
|
||||
- `jq` - JSON processing
|
||||
- `curl` - HTTP requests
|
||||
- `bash` - Shell interpreter
|
||||
|
||||
Install on macOS: `brew install jq curl`
|
||||
Install on Ubuntu: `apt-get install jq curl`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Hooks not executing
|
||||
|
||||
1. Check hooks are in the correct location:
|
||||
```bash
|
||||
ls .cursor/hooks.json # Project-level
|
||||
ls ~/.cursor/hooks.json # User-level
|
||||
```
|
||||
|
||||
2. Verify scripts are executable:
|
||||
```bash
|
||||
chmod +x ~/.cursor/hooks/*.sh
|
||||
```
|
||||
|
||||
3. Check Cursor Settings → Hooks tab for configuration status
|
||||
|
||||
4. Check Hooks output channel in Cursor for error messages
|
||||
|
||||
### Worker not responding
|
||||
|
||||
1. Verify worker is running:
|
||||
```bash
|
||||
curl http://127.0.0.1:37777/api/readiness
|
||||
```
|
||||
|
||||
2. Check worker logs:
|
||||
```bash
|
||||
tail -f ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log
|
||||
```
|
||||
|
||||
3. Restart worker:
|
||||
```bash
|
||||
claude-mem restart
|
||||
```
|
||||
|
||||
### Observations not being saved
|
||||
|
||||
1. Monitor worker logs for incoming requests
|
||||
|
||||
2. Verify session was initialized via web viewer at `http://localhost:37777`
|
||||
|
||||
3. Test observation endpoint directly:
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:37777/api/sessions/observations \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"contentSessionId":"test","tool_name":"test","tool_input":{},"tool_response":{},"cwd":"/tmp"}'
|
||||
```
|
||||
|
||||
## Comparison with Claude Code Integration
|
||||
|
||||
| Feature | Claude Code | Cursor |
|
||||
|---------|-------------|--------|
|
||||
| Session Initialization | ✅ `SessionStart` hook | ✅ `beforeSubmitPrompt` hook |
|
||||
| Context Injection | ✅ `additionalContext` field | ✅ Auto-updated `.cursor/rules/` file |
|
||||
| Observation Capture | ✅ `PostToolUse` hook | ✅ `afterMCPExecution`, `afterShellExecution`, `afterFileEdit` |
|
||||
| Session Summary | ✅ `Stop` hook with transcript | ⚠️ `stop` hook (no transcript) |
|
||||
| MCP Search Tools | ✅ Full support | ✅ Full support (if MCP configured) |
|
||||
|
||||
## Files
|
||||
|
||||
- `hooks.json` - Hook configuration
|
||||
- `common.sh` - Shared utility functions
|
||||
- `session-init.sh` - Session initialization
|
||||
- `context-inject.sh` - Context/worker readiness hook
|
||||
- `save-observation.sh` - MCP and shell observation capture
|
||||
- `save-file-edit.sh` - File edit observation capture
|
||||
- `session-summary.sh` - Summary generation
|
||||
- `cursorrules-template.md` - Template for `.cursorrules` file
|
||||
|
||||
## See Also
|
||||
|
||||
- [Claude-Mem Documentation](https://docs.claude-mem.ai)
|
||||
- [Cursor Hooks Reference](../docs/context/cursor-hooks-reference.md)
|
||||
- [Claude-Mem Architecture](https://docs.claude-mem.ai/architecture/overview)
|
||||
327
.agent/services/claude-mem/cursor-hooks/REVIEW.md
Normal file
327
.agent/services/claude-mem/cursor-hooks/REVIEW.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# Comprehensive Review: Cursor Hooks Integration
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a thorough review of the Cursor hooks integration, covering all aspects from implementation details to edge cases and potential issues.
|
||||
|
||||
## Architecture Review
|
||||
|
||||
### ✅ Strengths
|
||||
|
||||
1. **Modular Design**: Common utilities extracted to `common.sh` for reusability
|
||||
2. **Error Handling**: Graceful degradation - hooks never block Cursor even on failures
|
||||
3. **Parity with Claude Code**: Matches claude-mem's hook behavior where possible
|
||||
4. **Fire-and-Forget**: Observations sent asynchronously, don't block agent execution
|
||||
|
||||
### ⚠️ Limitations (Platform-Specific)
|
||||
|
||||
1. **No Windows Support**: Bash scripts require Unix-like environment
|
||||
- **Mitigation**: Could add PowerShell equivalents or use Node.js/Python wrappers
|
||||
2. **Dependency on jq/curl**: Requires external tools
|
||||
- **Mitigation**: Dependency checks added, graceful fallback
|
||||
|
||||
## Script-by-Script Review
|
||||
|
||||
### 1. `common.sh` - Utility Functions
|
||||
|
||||
**Purpose**: Shared utilities for all hook scripts
|
||||
|
||||
**Functions**:
|
||||
- ✅ `check_dependencies()` - Validates jq and curl exist
|
||||
- ✅ `read_json_input()` - Safely reads and validates JSON from stdin
|
||||
- ✅ `get_worker_port()` - Reads port from settings with validation
|
||||
- ✅ `ensure_worker_running()` - Health checks with retries
|
||||
- ✅ `url_encode()` - URL encoding for special characters
|
||||
- ✅ `get_project_name()` - Extracts project name with edge case handling
|
||||
- ✅ `json_get()` - Safe JSON field extraction with array support
|
||||
- ✅ `is_empty()` - Null/empty string detection
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty stdin
|
||||
- ✅ Malformed JSON
|
||||
- ✅ Missing settings file
|
||||
- ✅ Invalid port numbers
|
||||
- ✅ Windows drive roots (C:\, etc.)
|
||||
- ✅ Empty workspace roots
|
||||
- ✅ Array field access (`workspace_roots[0]`)
|
||||
|
||||
**Potential Issues**:
|
||||
- ⚠️ `url_encode()` uses jq - if jq fails, encoding fails silently
|
||||
- ✅ **Fixed**: Falls back to original string if encoding fails
|
||||
|
||||
### 2. `session-init.sh` - Session Initialization
|
||||
|
||||
**Purpose**: Initialize claude-mem session when prompt is submitted
|
||||
|
||||
**Flow**:
|
||||
1. Read and validate JSON input
|
||||
2. Extract session_id, project, prompt
|
||||
3. Ensure worker is running
|
||||
4. Strip leading slash from prompt (parity with new-hook.ts)
|
||||
5. Call `/api/sessions/init`
|
||||
6. Handle privacy checks
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty conversation_id → fallback to generation_id
|
||||
- ✅ Empty workspace_root → fallback to pwd
|
||||
- ✅ Empty prompt → still initializes session
|
||||
- ✅ Worker unavailable → graceful exit
|
||||
- ✅ Privacy-skipped sessions → silent exit
|
||||
- ✅ Invalid JSON → graceful exit
|
||||
|
||||
**Potential Issues**:
|
||||
- ✅ **Fixed**: String slicing now checks for empty strings
|
||||
- ✅ **Fixed**: All jq operations have error handling
|
||||
- ✅ **Fixed**: Worker health check with proper retries
|
||||
|
||||
**Parity with Claude Code**:
|
||||
- ✅ Session initialization
|
||||
- ✅ Privacy check handling
|
||||
- ✅ Slash stripping
|
||||
- ❌ SDK agent init (not applicable to Cursor)
|
||||
|
||||
### 3. `save-observation.sh` - Observation Capture
|
||||
|
||||
**Purpose**: Capture MCP tool usage and shell commands
|
||||
|
||||
**Flow**:
|
||||
1. Read and validate JSON input
|
||||
2. Determine hook type (MCP vs Shell)
|
||||
3. Extract tool data
|
||||
4. Validate JSON structures
|
||||
5. Ensure worker is running
|
||||
6. Send observation (fire-and-forget)
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty tool_name → exit gracefully
|
||||
- ✅ Invalid tool_input/tool_response → default to {}
|
||||
- ✅ Malformed JSON in tool data → validated and sanitized
|
||||
- ✅ Empty session_id → exit gracefully
|
||||
- ✅ Worker unavailable → exit gracefully
|
||||
|
||||
**Potential Issues**:
|
||||
- ✅ **Fixed**: JSON validation for tool_input and tool_response
|
||||
- ✅ **Fixed**: Proper handling of empty/null values
|
||||
- ✅ **Fixed**: Error handling for all jq operations
|
||||
|
||||
**Parity with Claude Code**:
|
||||
- ✅ Tool observation capture
|
||||
- ✅ Privacy tag stripping (handled by worker)
|
||||
- ✅ Fire-and-forget pattern
|
||||
- ✅ Enhanced: Shell command capture (not in Claude Code)
|
||||
|
||||
### 4. `save-file-edit.sh` - File Edit Capture
|
||||
|
||||
**Purpose**: Capture file edits as observations
|
||||
|
||||
**Flow**:
|
||||
1. Read and validate JSON input
|
||||
2. Extract file_path and edits array
|
||||
3. Validate edits array
|
||||
4. Create edit summary
|
||||
5. Ensure worker is running
|
||||
6. Send observation (fire-and-forget)
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty file_path → exit gracefully
|
||||
- ✅ Empty edits array → exit gracefully
|
||||
- ✅ Invalid edits JSON → default to []
|
||||
- ✅ Malformed edit objects → summary generation handles gracefully
|
||||
- ✅ Empty session_id → exit gracefully
|
||||
|
||||
**Potential Issues**:
|
||||
- ✅ **Fixed**: Edit summary generation with error handling
|
||||
- ✅ **Fixed**: Array validation before processing
|
||||
- ✅ **Fixed**: Safe string slicing in summary generation
|
||||
|
||||
**Parity with Claude Code**:
|
||||
- ✅ File edit capture (new feature for Cursor)
|
||||
- ✅ Observation format matches claude-mem structure
|
||||
|
||||
### 5. `session-summary.sh` - Summary Generation
|
||||
|
||||
**Purpose**: Generate session summary when agent loop ends
|
||||
|
||||
**Flow**:
|
||||
1. Read and validate JSON input
|
||||
2. Extract session_id
|
||||
3. Ensure worker is running
|
||||
4. Send summarize request with empty messages (no transcript access)
|
||||
5. Output empty JSON (required by Cursor)
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty session_id → exit gracefully
|
||||
- ✅ Worker unavailable → exit gracefully
|
||||
- ✅ Missing transcript → empty messages (worker handles gracefully)
|
||||
|
||||
**Potential Issues**:
|
||||
- ✅ **Fixed**: Proper JSON output for Cursor stop hook
|
||||
- ✅ **Fixed**: Worker handles empty messages (verified in codebase)
|
||||
|
||||
**Parity with Claude Code**:
|
||||
- ⚠️ Partial: No transcript access, so no last_user_message/last_assistant_message
|
||||
- ✅ Summary generation still works (based on observations)
|
||||
|
||||
### 6. `context-inject.sh` - Context Injection via Rules File
|
||||
|
||||
**Purpose**: Fetch context and write to `.cursor/rules/` for auto-injection
|
||||
|
||||
**How It Works**:
|
||||
1. Fetches context from claude-mem worker
|
||||
2. Writes to `.cursor/rules/claude-mem-context.mdc` with `alwaysApply: true`
|
||||
3. Cursor auto-includes this rule in all chat sessions
|
||||
4. Context refreshes on every prompt submission
|
||||
|
||||
**Flow**:
|
||||
1. Read and validate JSON input
|
||||
2. Extract workspace root
|
||||
3. Get project name
|
||||
4. Ensure worker is running
|
||||
5. Fetch context from `/api/context/inject`
|
||||
6. Write context to `.cursor/rules/claude-mem-context.mdc`
|
||||
7. Output `{"continue": true}`
|
||||
|
||||
**Edge Cases Handled**:
|
||||
- ✅ Empty workspace_root → fallback to pwd
|
||||
- ✅ Worker unavailable → allow prompt to continue
|
||||
- ✅ Context fetch failure → allow prompt to continue (no file written)
|
||||
- ✅ Special characters in project name → URL encoded
|
||||
- ✅ Missing `.cursor/rules/` directory → created automatically
|
||||
|
||||
**Parity with Claude Code**:
|
||||
- ✅ Context injection achieved via rules file workaround
|
||||
- ✅ Worker readiness check matches Claude Code
|
||||
- ✅ Context available immediately in next prompt
|
||||
|
||||
## Error Handling Review
|
||||
|
||||
### ✅ Comprehensive Error Handling
|
||||
|
||||
1. **Input Validation**:
|
||||
- ✅ Empty stdin → default to `{}`
|
||||
- ✅ Malformed JSON → validated and sanitized
|
||||
- ✅ Missing fields → safe fallbacks
|
||||
|
||||
2. **Dependency Checks**:
|
||||
- ✅ jq and curl existence checked
|
||||
- ✅ Non-blocking (warns but continues)
|
||||
|
||||
3. **Network Errors**:
|
||||
- ✅ Worker unavailable → graceful exit
|
||||
- ✅ HTTP failures → fire-and-forget (don't block)
|
||||
- ✅ Timeout handling → 15 second retries
|
||||
|
||||
4. **Data Validation**:
|
||||
- ✅ Port number validation (1-65535)
|
||||
- ✅ JSON structure validation
|
||||
- ✅ Empty/null value handling
|
||||
|
||||
## Security Review
|
||||
|
||||
### ✅ Security Considerations
|
||||
|
||||
1. **Input Sanitization**:
|
||||
- ✅ JSON validation prevents injection
|
||||
- ✅ URL encoding for special characters
|
||||
- ✅ Worker handles privacy tag stripping
|
||||
|
||||
2. **Error Information**:
|
||||
- ✅ Errors don't expose sensitive data
|
||||
- ✅ Fire-and-forget prevents information leakage
|
||||
|
||||
3. **Dependency Security**:
|
||||
- ✅ Uses standard tools (jq, curl)
|
||||
- ✅ No custom code execution
|
||||
|
||||
## Performance Review
|
||||
|
||||
### ✅ Performance Optimizations
|
||||
|
||||
1. **Non-Blocking**:
|
||||
- ✅ All hooks exit quickly (don't block Cursor)
|
||||
- ✅ Observations sent asynchronously
|
||||
|
||||
2. **Efficient Health Checks**:
|
||||
- ✅ 200ms polling interval
|
||||
- ✅ 15 second maximum wait
|
||||
- ✅ Early exit on success
|
||||
|
||||
3. **Resource Usage**:
|
||||
- ✅ Minimal memory footprint
|
||||
- ✅ No long-running processes
|
||||
- ✅ Fire-and-forget HTTP requests
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
### Unit Tests Needed
|
||||
|
||||
1. **common.sh functions**:
|
||||
- [ ] Test `json_get()` with various field types
|
||||
- [ ] Test `get_project_name()` with edge cases
|
||||
- [ ] Test `url_encode()` with special characters
|
||||
- [ ] Test `ensure_worker_running()` with various states
|
||||
|
||||
2. **Hook scripts**:
|
||||
- [ ] Test with empty input
|
||||
- [ ] Test with malformed JSON
|
||||
- [ ] Test with missing fields
|
||||
- [ ] Test with worker unavailable
|
||||
- [ ] Test with invalid port numbers
|
||||
|
||||
### Integration Tests Needed
|
||||
|
||||
1. **End-to-end flow**:
|
||||
- [ ] Session initialization → observation capture → summary
|
||||
- [ ] Multiple concurrent hooks
|
||||
- [ ] Worker restart scenarios
|
||||
|
||||
2. **Edge cases**:
|
||||
- [ ] Very long prompts/commands
|
||||
- [ ] Special characters in paths
|
||||
- [ ] Unicode in tool inputs
|
||||
- [ ] Large file edits
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **Cursor Hook System**:
|
||||
- ✅ Context injection solved via `.cursor/rules/` file
|
||||
- ❌ No transcript access for summary generation
|
||||
- ❌ No SessionStart equivalent
|
||||
|
||||
2. **Platform Support**:
|
||||
- ⚠️ Bash scripts (Unix-like only)
|
||||
- ⚠️ Requires jq and curl
|
||||
|
||||
3. **Context Injection**:
|
||||
- ✅ Solved via auto-updated `.cursor/rules/claude-mem-context.mdc`
|
||||
- ✅ Context also available via MCP tools
|
||||
- ✅ Context also available via web viewer
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate Improvements
|
||||
|
||||
1. ✅ **DONE**: Comprehensive error handling
|
||||
2. ✅ **DONE**: Input validation
|
||||
3. ✅ **DONE**: Dependency checks
|
||||
4. ✅ **DONE**: URL encoding
|
||||
|
||||
### Future Enhancements
|
||||
|
||||
1. **Logging**: Add optional debug logging to help troubleshoot
|
||||
2. **Metrics**: Track hook execution times and success rates
|
||||
3. **Windows Support**: PowerShell or Node.js equivalents
|
||||
4. **Testing**: Automated test suite
|
||||
5. **Documentation**: More examples and troubleshooting guides
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Cursor hooks integration is **production-ready** with:
|
||||
- ✅ Comprehensive error handling
|
||||
- ✅ Input validation and sanitization
|
||||
- ✅ Graceful degradation
|
||||
- ✅ Feature parity with Claude Code hooks (where applicable)
|
||||
- ✅ Enhanced features (shell/file edit capture)
|
||||
|
||||
The implementation handles edge cases well and follows best practices for reliability and maintainability.
|
||||
|
||||
293
.agent/services/claude-mem/cursor-hooks/STANDALONE-SETUP.md
Normal file
293
.agent/services/claude-mem/cursor-hooks/STANDALONE-SETUP.md
Normal file
@@ -0,0 +1,293 @@
|
||||
# Claude-Mem for Cursor (No Claude Code Required)
|
||||
|
||||
> **Persistent AI Memory for Cursor - Zero Cost to Start**
|
||||
|
||||
## Overview
|
||||
|
||||
Use claude-mem's persistent memory in Cursor without a Claude Code subscription. Choose between free-tier providers (Gemini, OpenRouter) or paid options.
|
||||
|
||||
**What You Get**:
|
||||
- **Persistent memory** that survives across sessions - your AI remembers what it worked on
|
||||
- **Automatic capture** of MCP tools, shell commands, and file edits
|
||||
- **Context injection** via `.cursor/rules/` - relevant history included in every chat
|
||||
- **Web viewer** at http://localhost:37777 - browse and search your project history
|
||||
|
||||
**Why This Matters**: Every Cursor session starts fresh. Claude-mem bridges that gap - your AI agent builds cumulative knowledge about your codebase, decisions, and patterns over time.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### macOS / Linux
|
||||
- Cursor IDE
|
||||
- [Bun](https://bun.sh) (`curl -fsSL https://bun.sh/install | bash`)
|
||||
- Git
|
||||
- `jq` and `curl`:
|
||||
- **macOS**: `brew install jq curl`
|
||||
- **Linux**: `apt install jq curl`
|
||||
|
||||
### Windows
|
||||
- Cursor IDE
|
||||
- [Bun](https://bun.sh) (PowerShell: `powershell -c "irm bun.sh/install.ps1 | iex"`)
|
||||
- Git
|
||||
- PowerShell 5.1+ (included with Windows 10/11)
|
||||
|
||||
## Step 1: Clone Claude-Mem
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/thedotmack/claude-mem.git
|
||||
cd claude-mem
|
||||
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Build the project
|
||||
bun run build
|
||||
```
|
||||
|
||||
## Step 2: Configure Provider (Choose One)
|
||||
|
||||
Since you don't have Claude Code, you need to configure an AI provider for claude-mem's summarization engine.
|
||||
|
||||
### Option A: Gemini (Recommended - Free Tier)
|
||||
|
||||
Gemini offers 1500 free requests per day, plenty for typical usage.
|
||||
|
||||
```bash
|
||||
# Create settings directory
|
||||
mkdir -p ~/.claude-mem
|
||||
|
||||
# Create settings file
|
||||
cat > ~/.claude-mem/settings.json << 'EOF'
|
||||
{
|
||||
"CLAUDE_MEM_PROVIDER": "gemini",
|
||||
"CLAUDE_MEM_GEMINI_API_KEY": "YOUR_GEMINI_API_KEY",
|
||||
"CLAUDE_MEM_GEMINI_MODEL": "gemini-2.5-flash-lite",
|
||||
"CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED": true
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Get your free API key**: https://aistudio.google.com/apikey
|
||||
|
||||
### Option B: OpenRouter (100+ Models)
|
||||
|
||||
OpenRouter provides access to many models, including free options.
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.claude-mem
|
||||
cat > ~/.claude-mem/settings.json << 'EOF'
|
||||
{
|
||||
"CLAUDE_MEM_PROVIDER": "openrouter",
|
||||
"CLAUDE_MEM_OPENROUTER_API_KEY": "YOUR_OPENROUTER_API_KEY"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Get your API key**: https://openrouter.ai/keys
|
||||
|
||||
**Free models available**:
|
||||
- `google/gemini-2.0-flash-exp:free`
|
||||
- `xiaomi/mimo-v2-flash:free`
|
||||
|
||||
### Option C: Claude API (If You Have API Access)
|
||||
|
||||
If you have Anthropic API credits but not a Claude Code subscription:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.claude-mem
|
||||
cat > ~/.claude-mem/settings.json << 'EOF'
|
||||
{
|
||||
"CLAUDE_MEM_PROVIDER": "claude",
|
||||
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
## Step 3: Install Cursor Hooks
|
||||
|
||||
```bash
|
||||
# From the claude-mem repo directory (recommended - all projects)
|
||||
bun run cursor:install -- user
|
||||
|
||||
# Or for project-level only:
|
||||
bun run cursor:install
|
||||
```
|
||||
|
||||
This installs:
|
||||
- Hook scripts to `.cursor/hooks/`
|
||||
- Hook configuration to `.cursor/hooks.json`
|
||||
- Context template to `.cursor/rules/`
|
||||
|
||||
## Step 4: Start the Worker
|
||||
|
||||
```bash
|
||||
bun run worker:start
|
||||
```
|
||||
|
||||
The worker runs in the background and handles:
|
||||
- Session management
|
||||
- Observation processing
|
||||
- AI-powered summarization
|
||||
- Context file updates
|
||||
|
||||
## Step 5: Restart Cursor & Verify
|
||||
|
||||
1. **Restart Cursor IDE** to load the new hooks
|
||||
|
||||
2. **Check installation status**:
|
||||
```bash
|
||||
bun run cursor:status
|
||||
```
|
||||
|
||||
3. **Verify the worker is running**:
|
||||
```bash
|
||||
curl http://127.0.0.1:37777/api/readiness
|
||||
```
|
||||
Should return: `{"status":"ready"}`
|
||||
|
||||
4. **Open the web viewer**: http://localhost:37777
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Before each prompt**: Hooks initialize a session and ensure the worker is running
|
||||
2. **During agent work**: MCP tools, shell commands, and file edits are captured
|
||||
3. **When agent stops**: Summary is generated and context file is updated
|
||||
4. **Next session**: Fresh context is automatically injected via `.cursor/rules/`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No provider configured" error
|
||||
|
||||
Verify your settings file exists and has valid credentials:
|
||||
```bash
|
||||
cat ~/.claude-mem/settings.json
|
||||
```
|
||||
|
||||
### Worker not starting
|
||||
|
||||
Check logs:
|
||||
```bash
|
||||
tail -f ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log
|
||||
```
|
||||
|
||||
### Hooks not executing
|
||||
|
||||
1. Check Cursor Settings → Hooks tab for errors
|
||||
2. Verify scripts are executable:
|
||||
```bash
|
||||
chmod +x ~/.cursor/hooks/*.sh
|
||||
```
|
||||
3. Check the Hooks output channel in Cursor
|
||||
|
||||
### Rate limiting (Gemini free tier)
|
||||
|
||||
If you hit the 1500 requests/day limit:
|
||||
- Wait until the next day
|
||||
- Upgrade to a paid plan
|
||||
- Switch to OpenRouter with a paid model
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Read [README.md](README.md) for detailed hook documentation
|
||||
- Check [CONTEXT-INJECTION.md](CONTEXT-INJECTION.md) for context behavior details
|
||||
- Visit https://docs.claude-mem.ai for full documentation
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `bun run cursor:install -- user` | Install hooks for all projects (recommended) |
|
||||
| `bun run cursor:install` | Install hooks for current project only |
|
||||
| `bun run cursor:status` | Check installation status |
|
||||
| `bun run worker:start` | Start the background worker |
|
||||
| `bun run worker:stop` | Stop the background worker |
|
||||
| `bun run worker:restart` | Restart the worker |
|
||||
|
||||
---
|
||||
|
||||
## Windows Installation
|
||||
|
||||
Windows users get full support via PowerShell scripts. The installer automatically detects Windows and installs the appropriate scripts.
|
||||
|
||||
### Enable Script Execution (if needed)
|
||||
|
||||
PowerShell may require you to enable script execution:
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||
```
|
||||
|
||||
### Step-by-Step for Windows
|
||||
|
||||
```powershell
|
||||
# Clone and build
|
||||
git clone https://github.com/thedotmack/claude-mem.git
|
||||
cd claude-mem
|
||||
bun install
|
||||
bun run build
|
||||
|
||||
# Configure provider (Gemini example)
|
||||
$settingsDir = "$env:USERPROFILE\.claude-mem"
|
||||
New-Item -ItemType Directory -Force -Path $settingsDir
|
||||
|
||||
@"
|
||||
{
|
||||
"CLAUDE_MEM_PROVIDER": "gemini",
|
||||
"CLAUDE_MEM_GEMINI_API_KEY": "YOUR_GEMINI_API_KEY"
|
||||
}
|
||||
"@ | Out-File -FilePath "$settingsDir\settings.json" -Encoding UTF8
|
||||
|
||||
# Interactive setup (recommended - walks you through everything)
|
||||
bun run cursor:setup
|
||||
|
||||
# Or manual installation
|
||||
bun run cursor:install
|
||||
bun run worker:start
|
||||
```
|
||||
|
||||
### What Gets Installed on Windows
|
||||
|
||||
The installer copies these PowerShell scripts to `.cursor\hooks\`:
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `common.ps1` | Shared utilities |
|
||||
| `session-init.ps1` | Initialize session on prompt |
|
||||
| `context-inject.ps1` | Inject memory context |
|
||||
| `save-observation.ps1` | Capture MCP/shell usage |
|
||||
| `save-file-edit.ps1` | Capture file edits |
|
||||
| `session-summary.ps1` | Generate summary on stop |
|
||||
|
||||
The `hooks.json` file is configured to invoke PowerShell with `-ExecutionPolicy Bypass` to ensure scripts run without additional configuration.
|
||||
|
||||
### Windows Troubleshooting
|
||||
|
||||
**"Execution of scripts is disabled on this system"**
|
||||
|
||||
Run as Administrator:
|
||||
```powershell
|
||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
|
||||
```
|
||||
|
||||
**PowerShell scripts not running**
|
||||
|
||||
Verify the hooks.json contains PowerShell invocations:
|
||||
```powershell
|
||||
Get-Content .cursor\hooks.json
|
||||
```
|
||||
|
||||
Should show commands like:
|
||||
```
|
||||
powershell.exe -ExecutionPolicy Bypass -File "./.cursor/hooks/session-init.ps1"
|
||||
```
|
||||
|
||||
**Worker not responding**
|
||||
|
||||
Check if port 37777 is in use:
|
||||
```powershell
|
||||
Get-NetTCPConnection -LocalPort 37777
|
||||
```
|
||||
|
||||
**Antivirus blocking scripts**
|
||||
|
||||
Some antivirus software may block PowerShell scripts. Add an exception for the `.cursor\hooks\` directory if needed.
|
||||
@@ -0,0 +1,84 @@
|
||||
# Claude-Mem Rules for Cursor
|
||||
|
||||
## Automatic Context Injection
|
||||
|
||||
The `context-inject.sh` hook **automatically creates and updates** a rules file at:
|
||||
|
||||
```
|
||||
.cursor/rules/claude-mem-context.mdc
|
||||
```
|
||||
|
||||
This file:
|
||||
- Has `alwaysApply: true` so it's included in every chat session
|
||||
- Contains recent context from past sessions
|
||||
- Auto-refreshes on every prompt submission
|
||||
|
||||
**You don't need to manually create any rules file!**
|
||||
|
||||
## Optional: Additional Instructions
|
||||
|
||||
If you want to add custom instructions about claude-mem (beyond the auto-injected context), create a separate rules file:
|
||||
|
||||
### `.cursor/rules/claude-mem-instructions.mdc`
|
||||
|
||||
```markdown
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Instructions for using claude-mem memory system"
|
||||
---
|
||||
|
||||
# Memory System Usage
|
||||
|
||||
You have access to claude-mem, a persistent memory system. In addition to the auto-injected context above, you can search for more detailed information using MCP tools:
|
||||
|
||||
## Available MCP Tools
|
||||
|
||||
1. **search** - Find relevant past observations
|
||||
```
|
||||
search(query="authentication bug", project="my-project", limit=10)
|
||||
```
|
||||
|
||||
2. **timeline** - Get context around a specific observation
|
||||
```
|
||||
timeline(anchor=<observation_id>, depth_before=3, depth_after=3)
|
||||
```
|
||||
|
||||
3. **get_observations** - Fetch full details for specific IDs
|
||||
```
|
||||
get_observations(ids=[123, 456])
|
||||
```
|
||||
|
||||
## When to Search Memory
|
||||
|
||||
- When the user asks about previous work or decisions
|
||||
- When encountering unfamiliar code patterns in this project
|
||||
- When debugging issues that might have been addressed before
|
||||
- When asked to continue or build upon previous work
|
||||
|
||||
## 3-Layer Workflow
|
||||
|
||||
Follow this pattern for token efficiency:
|
||||
1. **Search first** - Get compact index (~50-100 tokens/result)
|
||||
2. **Timeline** - Get chronological context around interesting results
|
||||
3. **Fetch details** - Only for relevant observations (~500-1000 tokens/result)
|
||||
|
||||
Never fetch full details without filtering first.
|
||||
```
|
||||
|
||||
## File Locations
|
||||
|
||||
| File | Purpose | Created By |
|
||||
|------|---------|------------|
|
||||
| `.cursor/rules/claude-mem-context.mdc` | Auto-injected context | Hook (automatic) |
|
||||
| `.cursor/rules/claude-mem-instructions.mdc` | MCP tool instructions | You (optional) |
|
||||
|
||||
## Git Ignore
|
||||
|
||||
If you don't want to commit the auto-generated context file:
|
||||
|
||||
```gitignore
|
||||
# .gitignore
|
||||
.cursor/rules/claude-mem-context.mdc
|
||||
```
|
||||
|
||||
The instructions file can be committed to share with your team.
|
||||
34
.agent/services/claude-mem/cursor-hooks/hooks.json
Normal file
34
.agent/services/claude-mem/cursor-hooks/hooks.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"version": 1,
|
||||
"hooks": {
|
||||
"beforeSubmitPrompt": [
|
||||
{
|
||||
"command": "./cursor-hooks/session-init.sh"
|
||||
},
|
||||
{
|
||||
"command": "./cursor-hooks/context-inject.sh"
|
||||
}
|
||||
],
|
||||
"afterMCPExecution": [
|
||||
{
|
||||
"command": "./cursor-hooks/save-observation.sh"
|
||||
}
|
||||
],
|
||||
"afterShellExecution": [
|
||||
{
|
||||
"command": "./cursor-hooks/save-observation.sh"
|
||||
}
|
||||
],
|
||||
"afterFileEdit": [
|
||||
{
|
||||
"command": "./cursor-hooks/save-file-edit.sh"
|
||||
}
|
||||
],
|
||||
"stop": [
|
||||
{
|
||||
"command": "./cursor-hooks/session-summary.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user