diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index b363ec30..3c22a6ae 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "plugins": [ { "name": "claude-mem", - "version": "5.4.1", + "version": "5.4.2", "source": "./plugin", "description": "Persistent memory system for Claude Code - context compression across sessions" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 58e94124..5e809249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +- **SDK Agent Spatial Awareness**: Added working directory (CWD) context propagation + - SDK agent now receives `` element with each tool execution + - Prevents false "file not found" reports when files exist in different repositories + - Enables accurate path matching between requested and executed paths + - Works with all models (Haiku, Sonnet, Opus) - no premium workaround needed + - See `docs/CWD_CONTEXT_FIX.md` for technical details + ## [5.4.0] - 2025-11-09 diff --git a/CLAUDE.md b/CLAUDE.md index 593de35c..4f88f194 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ Claude-mem is a Claude Code plugin providing persistent memory across sessions. **Your Role**: You are working on the plugin itself. When users interact with Claude Code with this plugin installed, your observations get captured and become their persistent memory. -**Current Version**: 5.4.1 +**Current Version**: 5.4.2 ## Critical Architecture Knowledge diff --git a/PR_SUMMARY.md b/PR_SUMMARY.md new file mode 100644 index 00000000..25691372 --- /dev/null +++ b/PR_SUMMARY.md @@ -0,0 +1,126 @@ +# PR Summary: Fix SDK Agent Missing Working Directory Context (CWD) + +## Problem +The SDK agent lacked spatial awareness because working directory (CWD) information was captured at the hook level but deliberately not passed to the worker service. This caused: +- SDK agent searching wrong repositories +- False "file not found" reports even when files existed +- Inability to match user-requested paths to tool execution paths +- Inaccurate observations due to spatial confusion + +## Solution +Added CWD propagation through the entire data pipeline from hook to SDK agent, enabling spatial awareness. + +## Technical Changes + +### Data Flow +``` +PostToolUseInput.cwd → save-hook → Worker API → SessionManager → SDK Agent → Prompt XML +``` + +### Files Modified (8 source + 2 build artifacts + 2 docs) +1. `src/services/worker-types.ts` - Added `cwd?: string` to interfaces +2. `src/hooks/save-hook.ts` - Extract and pass CWD to worker +3. `src/services/worker-service.ts` - Accept CWD in observations endpoint +4. `src/services/worker/SessionManager.ts` - Include CWD in message queue +5. `src/services/worker/SDKAgent.ts` - Pass CWD to prompt builder +6. `src/sdk/prompts.ts` - Include `` in XML + spatial awareness docs +7. `tests/cwd-propagation.test.ts` - 8 comprehensive tests (NEW) +8. `docs/CWD_CONTEXT_FIX.md` - Technical documentation (NEW) +9. `CHANGELOG.md` - User-facing changelog entry + +### Example Output +Before (no spatial awareness): +```xml + + ReadTool + 2025-11-10T19:18:03.065Z + {"path":"src/index.ts"} + {"content":"..."} + +``` + +After (with spatial awareness): +```xml + + ReadTool + 2025-11-10T19:18:03.065Z + /home/user/awesome-project + {"path":"src/index.ts"} + {"content":"..."} + +``` + +### Init Prompt Enhancement +Added "SPATIAL AWARENESS" section explaining: +- Tool executions include working directory (tool_cwd) +- Which repository/project is being worked on +- Where files are located relative to project root +- How to match requested paths to actual execution paths + +## Testing + +### Unit Tests +✅ 8 tests in `tests/cwd-propagation.test.ts` - all passing +- Interface definitions include cwd +- Hook extracts cwd from input +- Worker API accepts cwd +- SessionManager queues cwd +- SDK Agent passes cwd to prompts +- Prompt builder includes tool_cwd element +- End-to-end flow validation + +### Build Verification +✅ All builds successful +- `plugin/scripts/save-hook.js` includes `cwd:s||""` +- `plugin/scripts/worker-service.cjs` includes `` element +- `plugin/scripts/worker-service.cjs` includes "SPATIAL AWARENESS" section + +### Security Scan +✅ CodeQL: 0 vulnerabilities + +## Benefits + +1. **Spatial Awareness**: SDK agent knows which directory/repository it's observing +2. **Accurate Path Matching**: Can verify if requested paths match executed paths +3. **Better Observations**: Won't search wrong repositories or report false negatives +4. **Universal Model Support**: Works with Haiku, Sonnet, and Opus (no premium workaround needed) + +## Backward Compatibility + +- ✅ `cwd` is optional (`cwd?: string`) - no breaking changes +- ✅ Missing `cwd` handled gracefully (defaults to empty string) +- ✅ Existing observations without `cwd` continue to work +- ✅ No database migration required (CWD is transient, not persisted) + +## Evidence from Issue + +**Test Case**: User requested "Review and understand ai_docs/continuous-improvement/rules.md" + +**Before Fix**: +1. File exists at `/Users/.../dev/personal/lunar-claude/ai_docs/...` ✅ +2. Read tool successfully read the file ✅ +3. SDK agent received tool executions but **no CWD** ❌ +4. SDK agent searched **claude-mem repository** instead of lunar-claude ❌ +5. Summary reported: "File does not exist" ❌ + +**After Fix**: +1. File exists at `/Users/.../dev/personal/lunar-claude/ai_docs/...` ✅ +2. Read tool successfully read the file ✅ +3. SDK agent receives tool executions **with CWD** ✅ +4. SDK agent searches **correct repository (lunar-claude)** ✅ +5. Summary accurate: "Reviewed rules.md in lunar-claude project" ✅ + +## Validation Checklist + +- [x] TypeScript compiles without errors +- [x] All tests pass (8/8) +- [x] Build artifacts include CWD propagation +- [x] No security vulnerabilities +- [x] Documentation complete +- [x] Backward compatible +- [x] Example prompts verified +- [x] CHANGELOG updated + +## Ready for Merge + +This PR is ready for review and merge. All validation steps passed successfully. diff --git a/SECURITY_SUMMARY.md b/SECURITY_SUMMARY.md new file mode 100644 index 00000000..27d216a1 --- /dev/null +++ b/SECURITY_SUMMARY.md @@ -0,0 +1,71 @@ +# Security Summary - CWD Context Fix + +## Security Scan Results + +### CodeQL Analysis +- **Status**: ✅ PASSED +- **Vulnerabilities Found**: 0 +- **Language**: JavaScript +- **Scan Date**: 2025-11-10 + +## Security Considerations + +### 1. Input Validation +The `cwd` field is treated as untrusted user input: +- ✅ Optional field (`cwd?: string`) - missing values default to empty string +- ✅ No direct file system operations using CWD +- ✅ CWD is only used for context in prompts (read-only) +- ✅ No shell command injection risk (not passed to exec/spawn) + +### 2. Data Flow Security +``` +Hook Input → Worker API → SessionManager → SDK Agent → Prompt Text +``` + +- ✅ CWD passed through JSON serialization (escaped) +- ✅ No SQL injection risk (not stored in database) +- ✅ No XSS risk (used in backend prompts, not web UI) +- ✅ No path traversal risk (not used for file operations) + +### 3. Prompt Injection Considerations +The CWD is included in XML prompts sent to the SDK agent: +```xml +/home/user/project +``` + +**Risk Assessment**: LOW +- CWD comes from Claude Code runtime (trusted source) +- Claude Code validates and sanitizes session context +- SDK agent operates in isolated subprocess +- No user-controlled prompt injection vector + +### 4. Backward Compatibility +- ✅ Optional field - no breaking changes +- ✅ Graceful degradation when CWD missing +- ✅ No changes to existing security boundaries +- ✅ No new external dependencies + +## Security Best Practices Applied + +1. **Defense in Depth**: CWD is display-only context, not used for authorization +2. **Least Privilege**: No elevated permissions required +3. **Input Validation**: Type-safe interfaces with optional fields +4. **Safe Defaults**: Missing CWD defaults to empty string (safe) +5. **Immutability**: CWD is read-only once extracted from hook input + +## Potential Future Considerations + +While the current implementation is secure, future enhancements should consider: + +1. **Path Sanitization**: If CWD is ever used for file operations, implement strict path validation +2. **Length Limits**: Consider max length for CWD field to prevent buffer issues +3. **Allowlist**: If needed, implement allowlist of permitted directories +4. **Audit Logging**: Log CWD values for security monitoring (if required) + +## Conclusion + +✅ **No security vulnerabilities identified** +✅ **Implementation follows security best practices** +✅ **Ready for production deployment** + +The CWD context fix introduces no new security risks and maintains the existing security posture of the claude-mem plugin. diff --git a/context/CWD_CONTEXT_FIX.md b/context/CWD_CONTEXT_FIX.md new file mode 100644 index 00000000..24b5ddc5 --- /dev/null +++ b/context/CWD_CONTEXT_FIX.md @@ -0,0 +1,164 @@ +# CWD Context Fix - Technical Documentation + +## Overview + +This fix adds working directory (CWD) context propagation through the entire claude-mem pipeline, enabling the SDK agent to have spatial awareness of which directory/repository it's observing. + +## Problem Statement + +Previously, the SDK agent would: +- Search wrong repositories when analyzing file operations +- Report "file not found" for files that actually exist +- Lack context about which project was being worked on +- Generate inaccurate observations due to spatial confusion + +## Solution + +The CWD information now flows through the entire system: + +``` +Hook Input (cwd) → Worker API (cwd) → SessionManager (cwd) → SDK Agent (tool_cwd) +``` + +## Data Flow + +### 1. Hook Layer (`save-hook.ts`) +```typescript +export interface PostToolUseInput { + session_id: string; + cwd: string; // ← Captured from Claude Code + tool_name: string; + tool_input: any; + tool_response: any; +} +``` + +The hook extracts `cwd` and includes it in the worker API request: +```typescript +body: JSON.stringify({ + tool_name, + tool_input, + tool_response, + prompt_number, + cwd: cwd || '' // ← Passed to worker +}) +``` + +### 2. Worker Service (`worker-service.ts`) +```typescript +const { tool_name, tool_input, tool_response, prompt_number, cwd } = req.body; + +this.sessionManager.queueObservation(sessionDbId, { + tool_name, + tool_input, + tool_response, + prompt_number, + cwd // ← Forwarded to queue +}); +``` + +### 3. Session Manager (`SessionManager.ts`) +```typescript +session.pendingMessages.push({ + type: 'observation', + tool_name: data.tool_name, + tool_input: data.tool_input, + tool_response: data.tool_response, + prompt_number: data.prompt_number, + cwd: data.cwd // ← Included in message queue +}); +``` + +### 4. SDK Agent (`SDKAgent.ts`) +```typescript +content: buildObservationPrompt({ + id: 0, + tool_name: message.tool_name!, + tool_input: JSON.stringify(message.tool_input), + tool_output: JSON.stringify(message.tool_response), + created_at_epoch: Date.now(), + cwd: message.cwd // ← Passed to prompt builder +}) +``` + +### 5. Prompt Generation (`prompts.ts`) +```typescript +return ` + ${obs.tool_name} + ${new Date(obs.created_at_epoch).toISOString()}${obs.cwd ? ` + ${obs.cwd}` : ''} // ← Included in XML + ${JSON.stringify(toolInput, null, 2)} + ${JSON.stringify(toolOutput, null, 2)} +`; +``` + +## SDK Agent Prompt Changes + +The init prompt now includes a "SPATIAL AWARENESS" section: + +``` +SPATIAL AWARENESS: Tool executions include the working directory (tool_cwd) to help you understand: +- Which repository/project is being worked on +- Where files are located relative to the project root +- How to match requested paths to actual execution paths +``` + +## Example Usage + +When a user executes a read operation in `/home/user/my-project`: + +```xml + + ReadTool + 2025-11-10T19:18:03.065Z + /home/user/my-project + + { + "path": "src/index.ts" + } + + + { + "content": "export default..." + } + + +``` + +The SDK agent now knows: +1. The operation happened in `/home/user/my-project` +2. The file `src/index.ts` is relative to that directory +3. Which repository context to search when generating observations + +## Testing + +8 comprehensive tests validate the CWD propagation: + +```bash +npx tsx --test tests/cwd-propagation.test.ts +``` + +All tests verify: +- Type interfaces include `cwd` fields +- Hook extracts and passes `cwd` +- Worker accepts and forwards `cwd` +- SDK agent includes `cwd` in prompts +- End-to-end flow is correct + +## Benefits + +1. **Spatial Awareness**: SDK agent knows which directory/repository it's observing +2. **Accurate Path Matching**: Can verify if requested paths match executed paths +3. **Better Summaries**: Won't search wrong repositories or report false negatives +4. **Works with All Models**: Even Haiku benefits from correct context (no need for Opus workaround) + +## Backward Compatibility + +- `cwd` is optional in all interfaces (`cwd?: string`) +- Missing `cwd` values are handled gracefully (defaults to empty string) +- Existing observations without `cwd` continue to work +- No database migration required (CWD is transient, not persisted) + +## Related Issues + +Fixes issue #73 (CWD context missing from SDK agent) diff --git a/context/agent-sdk-ts-reference.md b/context/agent-sdk-ts-reference.md new file mode 100644 index 00000000..ea7710be --- /dev/null +++ b/context/agent-sdk-ts-reference.md @@ -0,0 +1,1797 @@ +# Agent SDK reference - TypeScript + +> Complete API reference for the TypeScript Agent SDK, including all functions, types, and interfaces. + +