276 lines
11 KiB
Markdown
276 lines
11 KiB
Markdown
# Phase 0 Task 3: Context Hook Logging Implementation
|
|
|
|
## Summary
|
|
|
|
Added comprehensive logging to the context hook (`src/hooks/context.ts`) to verify it correctly loads summaries from the database and outputs them as Claude's context. All logging uses `console.error` to avoid polluting stdout, which is reserved for the markdown context output that becomes part of Claude's context.
|
|
|
|
## Files Modified
|
|
|
|
- `/Users/alexnewman/Scripts/claude-mem/src/hooks/context.ts`
|
|
|
|
## Logging Points Added
|
|
|
|
All log messages use the `[claude-mem context]` prefix for easy searching and filtering.
|
|
|
|
### 1. Hook Invocation (Line 18-23)
|
|
```typescript
|
|
console.error('[claude-mem context] Hook fired with input:', JSON.stringify({
|
|
session_id: input?.session_id,
|
|
cwd: input?.cwd,
|
|
source: input?.source,
|
|
has_input: !!input
|
|
}));
|
|
```
|
|
**Purpose:** Logs that the hook was called and shows the input parameters, especially the `source` field which determines if context should be loaded.
|
|
|
|
### 2. Standalone Mode Detection (Line 27)
|
|
```typescript
|
|
console.error('[claude-mem context] No input provided - exiting (standalone mode)');
|
|
```
|
|
**Purpose:** Logs when the hook is run standalone without Claude Code input.
|
|
|
|
### 3. Source Check - Skip (Line 34)
|
|
```typescript
|
|
console.error('[claude-mem context] Source is not "startup" (got:', input.source, ') - skipping context load');
|
|
```
|
|
**Purpose:** Logs when the source is not "startup" (e.g., "resume"), indicating context loading is being skipped.
|
|
|
|
### 4. Source Check - Proceed (Line 39)
|
|
```typescript
|
|
console.error('[claude-mem context] Source check passed - proceeding with context load');
|
|
```
|
|
**Purpose:** Confirms we're proceeding with context loading because source check passed.
|
|
|
|
### 5. Project Extraction (Line 43)
|
|
```typescript
|
|
console.error('[claude-mem context] Extracted project name:', project, 'from cwd:', input.cwd);
|
|
```
|
|
**Purpose:** Shows the project name extracted from the cwd, which is used to query summaries.
|
|
|
|
### 6. Database Query Start (Line 46)
|
|
```typescript
|
|
console.error('[claude-mem context] Querying database for recent summaries...');
|
|
```
|
|
**Purpose:** Indicates we're about to query the database.
|
|
|
|
### 7. Database Query Results (Line 51)
|
|
```typescript
|
|
console.error('[claude-mem context] Database query complete - found', summaries.length, 'summaries');
|
|
```
|
|
**Purpose:** Reports how many summaries were found in the database.
|
|
|
|
### 8. Summary Previews (Lines 54-60)
|
|
```typescript
|
|
if (summaries.length > 0) {
|
|
console.error('[claude-mem context] Summary previews:');
|
|
summaries.forEach((summary, idx) => {
|
|
const preview = summary.request?.substring(0, 100) || summary.completed?.substring(0, 100) || '(no content)';
|
|
console.error(` [${idx + 1}]`, preview + (preview.length >= 100 ? '...' : ''));
|
|
});
|
|
}
|
|
```
|
|
**Purpose:** Shows a preview (first 100 chars) of each summary found, helping verify the correct data was retrieved.
|
|
|
|
### 9. No Summaries Found (Line 64)
|
|
```typescript
|
|
console.error('[claude-mem context] No summaries found - outputting empty context message');
|
|
```
|
|
**Purpose:** Logs when no summaries exist for the project.
|
|
|
|
### 10. Markdown Building Start (Line 70)
|
|
```typescript
|
|
console.error('[claude-mem context] Building markdown context from summaries...');
|
|
```
|
|
**Purpose:** Indicates we're starting to build the markdown output.
|
|
|
|
### 11. Markdown Output Details (Lines 117-120)
|
|
```typescript
|
|
console.error('[claude-mem context] Markdown built successfully');
|
|
console.error('[claude-mem context] Output length:', markdownOutput.length, 'characters,', output.length, 'lines');
|
|
console.error('[claude-mem context] Output preview (first 200 chars):', markdownOutput.substring(0, 200) + '...');
|
|
console.error('[claude-mem context] Outputting context to stdout for Claude Code injection');
|
|
```
|
|
**Purpose:** Reports the markdown was built successfully, shows its length, and provides a preview before sending to stdout.
|
|
|
|
### 12. Successful Completion (Line 125)
|
|
```typescript
|
|
console.error('[claude-mem context] Context hook completed successfully');
|
|
```
|
|
**Purpose:** Confirms the hook completed without errors.
|
|
|
|
### 13. Error Handling (Lines 130-133)
|
|
```typescript
|
|
console.error('[claude-mem context] ERROR occurred during context hook execution');
|
|
console.error('[claude-mem context] Error message:', error.message);
|
|
console.error('[claude-mem context] Error stack:', error.stack);
|
|
console.error('[claude-mem context] Exiting gracefully to avoid blocking Claude Code');
|
|
```
|
|
**Purpose:** Provides detailed error information if anything goes wrong, including stack trace for debugging.
|
|
|
|
## Critical Implementation Detail: stdout vs stderr
|
|
|
|
**IMPORTANT:** All logging uses `console.error` (stderr) because:
|
|
- The context hook outputs markdown to `console.log` (stdout)
|
|
- Claude Code reads stdout to inject context into Claude's conversation
|
|
- Any logging to stdout would pollute the context and break the feature
|
|
- stderr is safe for logging and will appear in Claude Code's logs/terminal
|
|
|
|
## How to Test
|
|
|
|
### Testing with an Existing Project with Summaries
|
|
|
|
1. **Ensure you have previous summaries saved:**
|
|
```bash
|
|
# Check if summaries exist for your project
|
|
sqlite3 ~/.config/claude-code/hooks/claude-mem.db "SELECT * FROM summaries WHERE project = 'your-project-name' LIMIT 5;"
|
|
```
|
|
|
|
2. **Start a new Claude Code session:**
|
|
```bash
|
|
cd /path/to/your-project
|
|
claude-code
|
|
```
|
|
|
|
3. **Check the logs:**
|
|
- Look for `[claude-mem context]` messages in stderr
|
|
- Claude Code should show these logs during startup
|
|
- The context should appear in Claude's initial knowledge
|
|
|
|
### Testing with a New Project (No Summaries)
|
|
|
|
1. **Navigate to a project without previous summaries:**
|
|
```bash
|
|
cd /path/to/new-project
|
|
claude-code
|
|
```
|
|
|
|
2. **Expected behavior:**
|
|
- Hook fires and logs indicate no summaries found
|
|
- Output should be: "No previous sessions found for this project yet."
|
|
|
|
### Testing Standalone Mode
|
|
|
|
```bash
|
|
# Run the hook directly (not via Claude Code)
|
|
tsx src/hooks/context.ts
|
|
|
|
# Expected output:
|
|
# [claude-mem context] Hook fired with input: {...}
|
|
# [claude-mem context] No input provided - exiting (standalone mode)
|
|
# No input provided - this script is designed to run as a Claude Code SessionStart hook
|
|
```
|
|
|
|
### Testing Source Check (Resume vs Startup)
|
|
|
|
The hook should only load context on `source: "startup"`, not on session resume. This is harder to test directly but the logs will show:
|
|
- On startup: "Source check passed - proceeding with context load"
|
|
- On resume: "Source is not 'startup' (got: resume) - skipping context load"
|
|
|
|
## Expected Log Sequence for a Session with Previous Summaries
|
|
|
|
When you start Claude Code in a project with existing summaries, you should see this sequence in stderr:
|
|
|
|
```
|
|
[claude-mem context] Hook fired with input: {"session_id":"...","cwd":"/path/to/project","source":"startup","has_input":true}
|
|
[claude-mem context] Source check passed - proceeding with context load
|
|
[claude-mem context] Extracted project name: project from cwd: /path/to/project
|
|
[claude-mem context] Querying database for recent summaries...
|
|
[claude-mem context] Database query complete - found 3 summaries
|
|
[claude-mem context] Summary previews:
|
|
[1] Added logging to the save hook to track when summaries are being persisted to the database...
|
|
[2] Implemented the worker hook to generate summaries from session transcripts using Claude API...
|
|
[3] Created database schema and initial setup for storing session summaries...
|
|
[claude-mem context] Building markdown context from summaries...
|
|
[claude-mem context] Markdown built successfully
|
|
[claude-mem context] Output length: 1247 characters, 45 lines
|
|
[claude-mem context] Output preview (first 200 chars): # Recent Session Context
|
|
|
|
Here's what happened in recent project sessions:
|
|
|
|
---
|
|
|
|
**Request:** Added logging to the save hook to track when summaries are being persisted to the database
|
|
|
|
**Completed:** ...
|
|
[claude-mem context] Outputting context to stdout for Claude Code injection
|
|
[claude-mem context] Context hook completed successfully
|
|
```
|
|
|
|
## What to Look For in Logs
|
|
|
|
### Success Indicators
|
|
1. Hook fires with `has_input: true` and `source: "startup"`
|
|
2. Source check passes
|
|
3. Project name is correctly extracted
|
|
4. Database query finds summaries (count > 0)
|
|
5. Summary previews show meaningful content
|
|
6. Markdown is built with reasonable length (> 100 characters)
|
|
7. Hook completes successfully
|
|
|
|
### Warning Signs
|
|
1. Hook fires with `has_input: false` - means Claude Code didn't provide input
|
|
2. Source is not "startup" - context won't load (expected on resume)
|
|
3. Database query finds 0 summaries - either first session or save hook not working
|
|
4. Summary previews show "(no content)" - data might be corrupt
|
|
5. Markdown length is very small - formatting might be broken
|
|
6. Error messages appear - check stack trace for issues
|
|
|
|
### Common Issues to Debug
|
|
|
|
**No summaries found:**
|
|
- Check if save hook is configured and working
|
|
- Verify worker hook generated summaries
|
|
- Ensure project name matches (case-sensitive)
|
|
|
|
**Hook doesn't fire:**
|
|
- Verify hooks are configured in Claude Code settings
|
|
- Check that the hook path is correct
|
|
- Ensure the built JavaScript exists (`dist/hooks/context.js`)
|
|
|
|
**Context not appearing in Claude:**
|
|
- Check if markdown is being output to stdout (should see in logs)
|
|
- Verify stdout isn't being polluted by other logs
|
|
- Check Claude Code configuration for SessionStart hooks
|
|
|
|
## Issues or Concerns Discovered
|
|
|
|
### None - Implementation is Clean
|
|
|
|
The implementation is straightforward and follows best practices:
|
|
|
|
1. **Separation of concerns:** stdout for context, stderr for logging
|
|
2. **Comprehensive coverage:** Every critical step is logged
|
|
3. **Safe error handling:** Errors are logged but don't block Claude Code
|
|
4. **No performance impact:** Logging is lightweight
|
|
5. **Easy debugging:** All logs are prefixed and searchable
|
|
|
|
### Future Enhancements (Optional)
|
|
|
|
1. **Log levels:** Could add debug/info/error levels for filtering
|
|
2. **Timing information:** Could log how long database queries take
|
|
3. **Conditional logging:** Could enable/disable via environment variable
|
|
4. **Structured logging:** Could output logs as JSON for parsing
|
|
|
|
## Testing Checklist
|
|
|
|
- [ ] Start Claude Code in a project with existing summaries
|
|
- [ ] Verify logs appear in stderr with `[claude-mem context]` prefix
|
|
- [ ] Confirm context appears in Claude's initial knowledge
|
|
- [ ] Check summary previews match actual summary content
|
|
- [ ] Verify markdown length is reasonable
|
|
- [ ] Test with a new project (no summaries)
|
|
- [ ] Confirm "No previous sessions found" message appears
|
|
- [ ] Run hook standalone and verify it exits gracefully
|
|
- [ ] Check that all log points are hit in sequence
|
|
- [ ] Verify no logs appear in stdout (only markdown context)
|
|
|
|
## Conclusion
|
|
|
|
The context hook now has comprehensive logging at every critical step. This will make it easy to:
|
|
- Verify summaries are being loaded from the database
|
|
- Debug issues with context not appearing
|
|
- Confirm the markdown output is correct
|
|
- Track the complete flow from hook invocation to Claude context injection
|
|
|
|
All logging uses stderr to avoid polluting the stdout channel that carries the actual context markdown to Claude Code.
|