diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8d6e2b20..6fb33002 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "plugins": [ { "name": "claude-mem", - "version": "5.1.4", + "version": "5.2.0", "source": "./plugin", "description": "Persistent memory system for Claude Code - context compression across sessions" } diff --git a/CLAUDE.md b/CLAUDE.md index 52a31311..bc3c579f 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.1.4 +**Current Version**: 5.2.0 ## Critical Architecture Knowledge diff --git a/PLAN-full-observation-display.md b/PLAN-full-observation-display.md new file mode 100644 index 00000000..8a404c17 --- /dev/null +++ b/PLAN-full-observation-display.md @@ -0,0 +1,468 @@ +# Plan: Display Complete Observation Data in Viewer UI + +## Current State Analysis + +### What's Currently Shown (5 fields) +- ✅ **type** - Displayed as chip/badge (e.g., "discovery", "bugfix") +- ✅ **project** - Shown in card header +- ✅ **title** - Main card title (shows "Untitled" if null) +- ✅ **subtitle** - Optional subheading +- ✅ **id + created_at** - Metadata line (e.g., "#1 • 2 hours ago") + +### What's Hidden (10+ fields) +- ❌ **narrative** - Detailed explanation text (MOST IMPORTANT) +- ❌ **facts** - JSON array of key facts (structured bullet points) +- ❌ **concepts** - JSON array of concept tags (e.g., "problem-solution", "gotcha") +- ❌ **files_read** - JSON array of file paths that were read +- ❌ **files_modified** - JSON array of file paths that were modified +- ❌ **text** - Legacy unstructured text field (deprecated but still populated) +- ❌ **prompt_number** - Which user prompt triggered this observation +- ❌ **sdk_session_id** - Session identifier + +### Database Schema (Actual Structure) + +```sql +observations table: +- id (INTEGER PRIMARY KEY) +- sdk_session_id (TEXT) +- project (TEXT) +- type (TEXT: decision, bugfix, feature, refactor, discovery, change) +- created_at (TEXT ISO timestamp) +- created_at_epoch (INTEGER milliseconds) +- prompt_number (INTEGER nullable) +- title (TEXT nullable) +- subtitle (TEXT nullable) +- narrative (TEXT nullable) -- Rich detailed explanation +- text (TEXT nullable) -- Legacy field +- facts (TEXT nullable) -- JSON array of key facts +- concepts (TEXT nullable) -- JSON array of concept tags +- files_read (TEXT nullable) -- JSON array of file paths +- files_modified (TEXT nullable) -- JSON array of file paths +``` + +### Issues Found + +1. **Type Definition Mismatch**: Three different type definitions exist: + - Actual database schema (most complete) + - `worker-types.ts` Observation interface (flattened, has wrong field names) + - `viewer/types.ts` Observation interface (minimal subset) + +2. **Data Loss**: Rich fields are stored in DB but not transmitted to UI: + - narrative, facts, files_read, files_modified all missing from API + +3. **PaginationHelper Query Bug**: Selects non-existent fields: + - `session_db_id` (should be `sdk_session_id`) + - `claude_session_id` (doesn't exist in observations table) + - `files` (should be `files_read` + `files_modified`) + +## Proposed Implementation Plan + +### Phase 1: Fix Data Layer + +#### 1.1 Update Viewer Type Definitions +**File**: `src/ui/viewer/types.ts` + +```typescript +export interface Observation { + id: number; + sdk_session_id: string; + project: string; + type: string; + title: string | null; + subtitle: string | null; + narrative: string | null; // NEW - detailed explanation + text: string | null; // Legacy field + facts: string | null; // NEW - JSON array of key facts + concepts: string | null; // NEW - JSON array of concept tags + files_read: string | null; // NEW - JSON array of file paths + files_modified: string | null; // NEW - JSON array of file paths + prompt_number: number | null; // NEW - which prompt triggered this + created_at: string; + created_at_epoch: number; +} +``` + +#### 1.2 Fix PaginationHelper SQL Query +**File**: `src/services/worker/PaginationHelper.ts` (around line 26) + +**Current (BROKEN)**: +```typescript +const fields = 'id, session_db_id, claude_session_id, project, type, title, subtitle, text, concepts, files, prompt_number, created_at, created_at_epoch'; +``` + +**Fixed**: +```typescript +const fields = 'id, sdk_session_id, project, type, title, subtitle, narrative, text, facts, concepts, files_read, files_modified, prompt_number, created_at, created_at_epoch'; +``` + +#### 1.3 Update Worker Service v2 Response Mapping +**File**: `src/services/worker-service-v2.ts` + +Ensure the `/api/observations` endpoint properly maps all fields from database to response. May need to parse JSON fields (facts, concepts, files_read, files_modified) if they're stored as JSON strings. + +### Phase 2: Redesign UI Component + +#### 2.1 Update ObservationCard Component +**File**: `src/ui/viewer/components/ObservationCard.tsx` + +**New Structure**: +``` +┌─────────────────────────────────────────┐ +│ [type badge] [project] │ ← Header (always visible) +├─────────────────────────────────────────┤ +│ Title │ ← Always visible +│ Subtitle (if present) │ ← Always visible +│ #123 • 2 hours ago [▼ More]│ ← Metadata + Expand button +├─────────────────────────────────────────┤ +│ │ +│ ┌─ EXPANDED CONTENT (when opened) ───┐ │ +│ │ │ │ +│ │ 📝 Narrative │ │ +│ │ ─────────────────────────────────── │ │ +│ │ Detailed explanation text... │ │ +│ │ │ │ +│ │ 📌 Key Facts │ │ +│ │ ─────────────────────────────────── │ │ +│ │ • Fact 1 │ │ +│ │ • Fact 2 │ │ +│ │ • Fact 3 │ │ +│ │ │ │ +│ │ 🏷️ Concepts │ │ +│ │ ─────────────────────────────────── │ │ +│ │ [problem-solution] [discovery] │ │ +│ │ │ │ +│ │ 📁 Files │ │ +│ │ ─────────────────────────────────── │ │ +│ │ 📖 Read: │ │ +│ │ src/hooks/save-hook.ts │ │ +│ │ src/services/worker.ts │ │ +│ │ ✏️ Modified: │ │ +│ │ src/hooks/save-hook.ts │ │ +│ │ │ │ +│ │ 🔗 Session Info │ │ +│ │ ─────────────────────────────────── │ │ +│ │ Prompt #5 • Session: abc123... │ │ +│ │ │ │ +│ └─────────────────────────────────────┘ │ +└─────────────────────────────────────────┘ +``` + +**Component Logic**: +```typescript +const ObservationCard = ({ observation }) => { + const [isExpanded, setIsExpanded] = useState(false); + + // Parse JSON fields + const facts = observation.facts ? JSON.parse(observation.facts) : []; + const concepts = observation.concepts ? JSON.parse(observation.concepts) : []; + const filesRead = observation.files_read ? JSON.parse(observation.files_read) : []; + const filesModified = observation.files_modified ? JSON.parse(observation.files_modified) : []; + + return ( +
+ {/* Header - always visible */} +
+ + {observation.type} + + {observation.project} +
+ + {/* Title/Subtitle - always visible */} +
{observation.title || 'Untitled'}
+ {observation.subtitle && ( +
{observation.subtitle}
+ )} + + {/* Metadata + Expand button - always visible */} +
+ #{observation.id} • {formatDate(observation.created_at_epoch)} + +
+ + {/* Expanded content - conditional */} + {isExpanded && ( +
+ + {/* Narrative Section */} + {observation.narrative && ( +
+
📝 Narrative
+
+ {observation.narrative} +
+
+ )} + + {/* Facts Section */} + {facts.length > 0 && ( +
+
📌 Key Facts
+
    + {facts.map((fact, i) => ( +
  • {fact}
  • + ))} +
+
+ )} + + {/* Concepts Section */} + {concepts.length > 0 && ( +
+
🏷️ Concepts
+
+ {concepts.map((concept, i) => ( + {concept} + ))} +
+
+ )} + + {/* Files Section */} + {(filesRead.length > 0 || filesModified.length > 0) && ( +
+
📁 Files
+
+ {filesRead.length > 0 && ( +
+
📖 Read:
+ {filesRead.map((file, i) => ( +
{file}
+ ))} +
+ )} + {filesModified.length > 0 && ( +
+
✏️ Modified:
+ {filesModified.map((file, i) => ( +
{file}
+ ))} +
+ )} +
+
+ )} + + {/* Session Info Section */} +
+
🔗 Session Info
+
+ {observation.prompt_number && ( + Prompt #{observation.prompt_number} + )} + {observation.sdk_session_id && ( + + Session: {observation.sdk_session_id.substring(0, 8)}... + + )} +
+
+ +
+ )} +
+ ); +}; +``` + +### Phase 3: Style Enhancements + +#### 3.1 Update Styles +**File**: `src/ui/viewer/styles.css` + +**New CSS Classes Needed**: +```css +/* Expanded card state */ +.card-expanded { + /* Maybe increase shadow or border when expanded */ +} + +/* Expand toggle button */ +.expand-toggle { + background: none; + border: none; + color: var(--text-secondary); + cursor: pointer; + font-size: 12px; + padding: 4px 8px; + border-radius: 4px; +} +.expand-toggle:hover { + background: var(--bg-secondary); +} + +/* Expanded content container */ +.card-expanded-content { + margin-top: 16px; + padding-top: 16px; + border-top: 1px solid var(--border-color); + animation: expandDown 0.2s ease-out; +} + +@keyframes expandDown { + from { + opacity: 0; + transform: translateY(-8px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Section styling */ +.card-section { + margin-bottom: 16px; +} +.card-section:last-child { + margin-bottom: 0; +} + +.section-header { + font-weight: 600; + font-size: 13px; + color: var(--text-primary); + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 6px; +} + +.section-content { + padding-left: 20px; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.6; +} + +/* Narrative styling */ +.narrative { + max-height: 300px; + overflow-y: auto; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* Facts list styling */ +.facts-list { + list-style: disc; + margin: 0; + padding-left: 20px; +} +.facts-list li { + margin-bottom: 4px; +} + +/* Concepts tags */ +.concepts { + display: flex; + flex-wrap: wrap; + gap: 6px; +} +.concept-tag { + background: var(--accent-bg); + color: var(--accent-text); + padding: 4px 10px; + border-radius: 12px; + font-size: 11px; + font-weight: 500; +} + +/* File paths */ +.file-group { + margin-bottom: 8px; +} +.file-group:last-child { + margin-bottom: 0; +} +.file-group-label { + font-weight: 500; + margin-bottom: 4px; + color: var(--text-primary); +} +.file-path { + font-family: 'SF Mono', 'Monaco', 'Courier New', monospace; + font-size: 12px; + padding: 4px 8px; + background: var(--code-bg); + border-radius: 4px; + margin-bottom: 2px; + overflow-x: auto; + white-space: nowrap; +} + +/* Session info */ +.session-info { + display: flex; + gap: 16px; + font-size: 12px; +} +.session-id { + font-family: 'SF Mono', 'Monaco', 'Courier New', monospace; + color: var(--text-tertiary); +} +``` + +## Implementation Steps (In Order) + +1. **Fix PaginationHelper query** (src/services/worker/PaginationHelper.ts) + - Update SQL SELECT to use correct field names + - Test with `npm run worker:restart:v2` + +2. **Update viewer type definitions** (src/ui/viewer/types.ts) + - Add all missing fields to Observation interface + +3. **Verify worker service v2 mapping** (src/services/worker-service-v2.ts) + - Ensure `/api/observations` returns all fields + - Test API response with curl or browser + +4. **Update ObservationCard component** (src/ui/viewer/components/ObservationCard.tsx) + - Add expand/collapse state + - Add all new sections (narrative, facts, concepts, files, session) + - Add expand toggle button + +5. **Update styles** (src/ui/viewer/styles.css) + - Add all new CSS classes for expanded content + - Add animations for smooth expand/collapse + - Style sections, lists, tags, file paths + +6. **Build and test** + ```bash + npm run build + npm run sync-marketplace + npm run worker:restart:v2 + ``` + +7. **Manual testing** + - Open http://localhost:37777 + - Click expand button on observations + - Verify all fields display correctly + - Test light/dark mode + - Test with observations that have missing fields (graceful fallback) + +## Success Criteria + +- [ ] All database fields are fetched in API query +- [ ] All fields are properly typed in TypeScript interfaces +- [ ] ObservationCard shows all data in expanded view +- [ ] Expand/collapse animations work smoothly +- [ ] File paths are formatted in monospace font +- [ ] Concepts display as tag pills +- [ ] Facts display as bulleted list +- [ ] Narrative text wraps properly with scroll for long content +- [ ] No console errors +- [ ] Works in both light and dark themes + +## Optional Enhancements (Future) + +- [ ] Remember expanded state in localStorage (persist across page refresh) +- [ ] Keyboard shortcuts (Space to expand/collapse focused card) +- [ ] Click file paths to copy to clipboard +- [ ] Search/filter by concepts or files +- [ ] Syntax highlighting for code in narrative +- [ ] Link session_id to session detail view diff --git a/context/agent-sdk-ref.md b/context/agent-sdk-ref.md new file mode 100644 index 00000000..28925155 --- /dev/null +++ b/context/agent-sdk-ref.md @@ -0,0 +1,1797 @@ +# Agent SDK reference - TypeScript + +> Complete API reference for the TypeScript Agent SDK, including all functions, types, and interfaces. + +