- docs/plan.md: Master roadmap with phases and priorities - docs/milestones/01-13: Detailed specs for each feature - Updated CLAUDE.md with plan references and build commands Milestones cover: - Phase 1: Temporal versioning, auto-capture, context injection, codebase indexing - Phase 2: Daily journal, content ingestion, graph visualization, import/export - Phase 3: Multi-graph, smart retrieval, TUI dashboard, browser extension, shell completions
239 lines
6.0 KiB
Markdown
239 lines
6.0 KiB
Markdown
# Milestone 3: Context Injection
|
|
|
|
## Overview
|
|
|
|
Automatically inject relevant memories into Claude's context at session start. Claude begins every conversation already "knowing" relevant history.
|
|
|
|
## Motivation
|
|
|
|
- Eliminates "Claude doesn't remember" frustration
|
|
- No manual "let me search my notes" workflow
|
|
- Supermemory's most impactful feature
|
|
- Makes memory system invisible to users
|
|
|
|
## Features
|
|
|
|
### 3.1 Session Start Hook
|
|
|
|
```json
|
|
// .claude/settings.json
|
|
{
|
|
"hooks": {
|
|
"session_start": {
|
|
"command": "cortex context-hook",
|
|
"timeout": 3000
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.2 Context Selection
|
|
|
|
Intelligently select what to inject:
|
|
|
|
```typescript
|
|
interface ContextSelection {
|
|
recentWork: Node[]; // Last 24-48 hours of activity
|
|
projectContext: Node[]; // Indexed codebase info
|
|
relevantMemories: Node[]; // Semantic match to current directory
|
|
userPreferences: Node[]; // User's stated preferences
|
|
openTasks: Node[]; // Incomplete tasks
|
|
}
|
|
```
|
|
|
|
### 3.3 Context Budget
|
|
|
|
Manage token usage with configurable limits:
|
|
|
|
```typescript
|
|
interface ContextConfig {
|
|
maxTokens: number; // Default: 4000
|
|
maxNodes: number; // Default: 20
|
|
includeRecent: boolean; // Include recent work
|
|
includeProject: boolean; // Include project index
|
|
includeTasks: boolean; // Include open tasks
|
|
customQuery?: string; // Additional filter query
|
|
}
|
|
```
|
|
|
|
### 3.4 Priority Ranking
|
|
|
|
Rank memories for inclusion:
|
|
|
|
1. **Project-specific** — Nodes tagged with current project
|
|
2. **Recent** — Accessed in last 48 hours
|
|
3. **Tasks** — Open todos/tasks
|
|
4. **High-relevance** — Semantic match to project files
|
|
5. **Decisions** — Past architectural decisions
|
|
|
|
### 3.5 MCP Resource
|
|
|
|
Expose context as an MCP resource:
|
|
|
|
```typescript
|
|
// MCP resource for context
|
|
{
|
|
uri: "memory://context/current",
|
|
name: "Current Context",
|
|
description: "Relevant memories for this session"
|
|
}
|
|
```
|
|
|
|
## Implementation
|
|
|
|
### Context Hook
|
|
|
|
```typescript
|
|
// src/cli/commands/context-hook.ts
|
|
export async function contextHook(): Promise<string> {
|
|
const cwd = process.cwd();
|
|
const projectName = path.basename(cwd);
|
|
|
|
// Gather context candidates
|
|
const candidates = await gatherCandidates(cwd, projectName);
|
|
|
|
// Rank and select within budget
|
|
const selected = selectWithinBudget(candidates, config.maxTokens);
|
|
|
|
// Format for Claude
|
|
return formatContext(selected);
|
|
}
|
|
|
|
async function gatherCandidates(cwd: string, project: string): Promise<RankedNode[]> {
|
|
const results: RankedNode[] = [];
|
|
|
|
// Recent work (last 48h)
|
|
const recent = await listNodes({
|
|
limit: 10,
|
|
// Custom: accessed in last 48h
|
|
});
|
|
results.push(...recent.map(n => ({ node: n, score: 0.8, reason: 'recent' })));
|
|
|
|
// Project-tagged nodes
|
|
const projectNodes = await listNodes({ tags: [project] });
|
|
results.push(...projectNodes.map(n => ({ node: n, score: 0.9, reason: 'project' })));
|
|
|
|
// Open tasks
|
|
const tasks = await listNodes({ kind: 'task', status: 'todo' });
|
|
results.push(...tasks.map(n => ({ node: n, score: 0.7, reason: 'task' })));
|
|
|
|
// Semantic search on README/package.json
|
|
const projectContext = await getProjectContext(cwd);
|
|
if (projectContext) {
|
|
const semantic = await query(projectContext, { limit: 10 });
|
|
results.push(...semantic.map(n => ({ node: n.node, score: n.score, reason: 'semantic' })));
|
|
}
|
|
|
|
return dedupeAndRank(results);
|
|
}
|
|
```
|
|
|
|
### Context Formatting
|
|
|
|
```typescript
|
|
function formatContext(nodes: RankedNode[]): string {
|
|
const sections: string[] = [];
|
|
|
|
// Group by reason
|
|
const byReason = groupBy(nodes, 'reason');
|
|
|
|
if (byReason.project?.length) {
|
|
sections.push(`## Project Context\n${formatNodes(byReason.project)}`);
|
|
}
|
|
|
|
if (byReason.recent?.length) {
|
|
sections.push(`## Recent Work\n${formatNodes(byReason.recent)}`);
|
|
}
|
|
|
|
if (byReason.task?.length) {
|
|
sections.push(`## Open Tasks\n${formatNodes(byReason.task)}`);
|
|
}
|
|
|
|
if (byReason.semantic?.length) {
|
|
sections.push(`## Related Memories\n${formatNodes(byReason.semantic)}`);
|
|
}
|
|
|
|
return sections.join('\n\n');
|
|
}
|
|
```
|
|
|
|
### Configuration
|
|
|
|
```bash
|
|
# Configure context injection
|
|
cortex config set context.maxTokens 4000
|
|
cortex config set context.maxNodes 20
|
|
cortex config set context.includeRecent true
|
|
cortex config set context.includeTasks true
|
|
```
|
|
|
|
## CLI Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `cortex context-hook` | Hook handler (outputs context to stdout) |
|
|
| `cortex context` | Preview what context would be injected |
|
|
| `cortex context --project <name>` | Show context for specific project |
|
|
|
|
## MCP Integration
|
|
|
|
```typescript
|
|
// MCP resource
|
|
server.resource({
|
|
uri: 'memory://context/current',
|
|
name: 'Session Context',
|
|
mimeType: 'text/markdown',
|
|
async read() {
|
|
const context = await generateContext();
|
|
return { text: context };
|
|
}
|
|
});
|
|
|
|
// MCP tool
|
|
server.tool('memory_context', 'Get relevant context for current session', {
|
|
project: z.string().optional(),
|
|
maxTokens: z.number().optional()
|
|
}, async ({ project, maxTokens }) => {
|
|
const context = await generateContext({ project, maxTokens });
|
|
return { content: [{ type: 'text', text: context }] };
|
|
});
|
|
```
|
|
|
|
## Testing
|
|
|
|
- [ ] Hook outputs valid markdown
|
|
- [ ] Context respects token budget
|
|
- [ ] Project-specific nodes ranked highest
|
|
- [ ] Recent nodes included
|
|
- [ ] Open tasks included
|
|
- [ ] No duplicate nodes in output
|
|
- [ ] Performance <500ms
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] Context auto-injected at session start
|
|
- [ ] Relevant memories appear without user action
|
|
- [ ] Token budget respected
|
|
- [ ] Configurable what to include
|
|
- [ ] Works in any project directory
|
|
- [ ] Graceful when no relevant memories
|
|
|
|
## Estimated Effort
|
|
|
|
- Hook implementation: 3 hours
|
|
- Context gathering: 4 hours
|
|
- Ranking algorithm: 3 hours
|
|
- Configuration: 2 hours
|
|
- MCP integration: 2 hours
|
|
- Testing: 2 hours
|
|
- **Total: ~16 hours**
|
|
|
|
## Dependencies
|
|
|
|
- Milestone 4 (Codebase Indexing) enhances this but not required
|
|
|
|
## References
|
|
|
|
- [Claude-Supermemory context injection](https://github.com/supermemoryai/claude-supermemory)
|
|
- [RAG best practices](https://www.anthropic.com/research/rag)
|