Add development plan with 13 milestone specifications
- 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
This commit is contained in:
249
docs/milestones/05-daily-journal.md
Normal file
249
docs/milestones/05-daily-journal.md
Normal file
@@ -0,0 +1,249 @@
|
||||
# Milestone 5: Daily Journal
|
||||
|
||||
## Overview
|
||||
|
||||
Quick-capture system for daily notes, thoughts, and todos. Every day gets its own node, making it easy to track what happened when.
|
||||
|
||||
## Motivation
|
||||
|
||||
- Logseq's daily notes are beloved by users
|
||||
- Low-friction capture encourages consistent use
|
||||
- Chronological organization aids recall
|
||||
- Natural integration with auto-capture
|
||||
|
||||
## Features
|
||||
|
||||
### 5.1 Daily Note Creation
|
||||
|
||||
```bash
|
||||
# Open/create today's journal
|
||||
cortex journal
|
||||
|
||||
# Add to today's journal
|
||||
cortex journal "Fixed the auth bug"
|
||||
cortex j "Quick thought" # Alias
|
||||
|
||||
# View specific day
|
||||
cortex journal --date 2024-01-15
|
||||
cortex journal --yesterday
|
||||
```
|
||||
|
||||
### 5.2 Quick Capture
|
||||
|
||||
Append to today's journal without opening it:
|
||||
|
||||
```bash
|
||||
# Quick capture
|
||||
cortex capture "Remember to update docs"
|
||||
cortex c "TODO: refactor auth" # Alias
|
||||
|
||||
# Capture with tags
|
||||
cortex capture "API rate limiting idea" --tags api,performance
|
||||
|
||||
# Capture from clipboard
|
||||
cortex capture --clipboard
|
||||
```
|
||||
|
||||
### 5.3 Journal Structure
|
||||
|
||||
```typescript
|
||||
interface JournalNode {
|
||||
kind: 'memory';
|
||||
title: string; // "Journal: 2024-01-15"
|
||||
content: string; // Markdown with entries
|
||||
tags: ['journal', 'daily', '2024-01', '2024'];
|
||||
metadata: {
|
||||
date: string; // "2024-01-15"
|
||||
entries: JournalEntry[];
|
||||
};
|
||||
}
|
||||
|
||||
interface JournalEntry {
|
||||
time: string; // "14:30"
|
||||
text: string;
|
||||
tags?: string[];
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 Journal Linking
|
||||
|
||||
Auto-link journals to related nodes:
|
||||
|
||||
- Mentioned node IDs → `relates_to` edge
|
||||
- Mentioned tags → find and link relevant nodes
|
||||
- Mentioned files → link to indexed components
|
||||
|
||||
### 5.5 End-of-Day Summary
|
||||
|
||||
Optional AI-generated summary:
|
||||
|
||||
```bash
|
||||
# Generate summary of today
|
||||
cortex journal --summarize
|
||||
|
||||
# Auto-summarize at end of day (cron/scheduled task)
|
||||
cortex journal --summarize --auto
|
||||
```
|
||||
|
||||
### 5.6 Journal Search
|
||||
|
||||
```bash
|
||||
# Search within journals
|
||||
cortex journal --search "auth bug"
|
||||
|
||||
# List recent journals
|
||||
cortex journal --list
|
||||
cortex journal --list --month 2024-01
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
### Journal Service
|
||||
|
||||
```typescript
|
||||
// src/core/journal.ts
|
||||
export async function getOrCreateJournal(date?: string): Promise<Node> {
|
||||
const targetDate = date || formatDate(new Date());
|
||||
const title = `Journal: ${targetDate}`;
|
||||
|
||||
// Find existing
|
||||
const existing = await findNodeByTitle(title);
|
||||
if (existing) return existing;
|
||||
|
||||
// Create new
|
||||
return addNode({
|
||||
kind: 'memory',
|
||||
title,
|
||||
content: `# ${targetDate}\n\n`,
|
||||
tags: ['journal', 'daily', ...dateTags(targetDate)],
|
||||
metadata: { date: targetDate, entries: [] },
|
||||
});
|
||||
}
|
||||
|
||||
export async function appendToJournal(text: string, options?: CaptureOptions): Promise<void> {
|
||||
const journal = await getOrCreateJournal();
|
||||
const time = formatTime(new Date());
|
||||
|
||||
const entry: JournalEntry = {
|
||||
time,
|
||||
text,
|
||||
tags: options?.tags,
|
||||
};
|
||||
|
||||
// Append to content
|
||||
const newContent = `${journal.content}\n- **${time}** ${text}`;
|
||||
|
||||
// Update metadata
|
||||
const entries = [...(journal.metadata.entries || []), entry];
|
||||
|
||||
await updateNode(journal.id, {
|
||||
content: newContent,
|
||||
metadata: { ...journal.metadata, entries },
|
||||
});
|
||||
|
||||
// Auto-link mentioned nodes
|
||||
await linkMentionedNodes(journal.id, text);
|
||||
}
|
||||
```
|
||||
|
||||
### Daily Summary Generator
|
||||
|
||||
```typescript
|
||||
async function generateDailySummary(date: string): Promise<string> {
|
||||
const journal = await getOrCreateJournal(date);
|
||||
if (!journal.metadata.entries?.length) return '';
|
||||
|
||||
const prompt = `
|
||||
Summarize this day's journal entries in 2-3 sentences.
|
||||
Focus on: accomplishments, decisions, blockers.
|
||||
|
||||
Entries:
|
||||
${journal.metadata.entries.map(e => `- ${e.time}: ${e.text}`).join('\n')}
|
||||
|
||||
Summary:`;
|
||||
|
||||
return generate(prompt);
|
||||
}
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `cortex journal` | Open today's journal |
|
||||
| `cortex journal <text>` | Add entry to today |
|
||||
| `cortex journal --date <date>` | View/edit specific day |
|
||||
| `cortex journal --yesterday` | Yesterday's journal |
|
||||
| `cortex journal --list` | List recent journals |
|
||||
| `cortex journal --search <query>` | Search journals |
|
||||
| `cortex journal --summarize` | Generate summary |
|
||||
| `cortex capture <text>` | Quick capture alias |
|
||||
| `cortex c <text>` | Even shorter alias |
|
||||
|
||||
## MCP Tools
|
||||
|
||||
```typescript
|
||||
memory_journal // Get/create today's journal
|
||||
memory_capture // Quick capture to journal
|
||||
memory_journal_list // List recent journals
|
||||
```
|
||||
|
||||
## Integration
|
||||
|
||||
### With Auto-Capture (Milestone 2)
|
||||
|
||||
Auto-captured conversations link to that day's journal:
|
||||
|
||||
```typescript
|
||||
// In auto-capture hook
|
||||
const journal = await getOrCreateJournal();
|
||||
addEdge(capturedNode.id, journal.id, 'relates_to', { reason: 'same-day' });
|
||||
```
|
||||
|
||||
### With Context Injection (Milestone 3)
|
||||
|
||||
Recent journal entries included in context:
|
||||
|
||||
```typescript
|
||||
// In context gathering
|
||||
const recentJournals = await getRecentJournals(3); // Last 3 days
|
||||
candidates.push(...recentJournals.map(j => ({ node: j, score: 0.6, reason: 'journal' })));
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
- [ ] Creates journal node for today
|
||||
- [ ] Appends entries with timestamps
|
||||
- [ ] `--date` flag accesses correct day
|
||||
- [ ] Search finds entries across journals
|
||||
- [ ] Summary generation works
|
||||
- [ ] Journal linked to mentioned nodes
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `cortex capture "text"` takes <100ms
|
||||
- [ ] Journals organized by date
|
||||
- [ ] Can search across all journals
|
||||
- [ ] Summary captures key points
|
||||
- [ ] Integrates with auto-capture
|
||||
- [ ] MCP tools work correctly
|
||||
|
||||
## Estimated Effort
|
||||
|
||||
- Journal CRUD: 3 hours
|
||||
- Quick capture: 2 hours
|
||||
- Search/list: 2 hours
|
||||
- Summary generation: 2 hours
|
||||
- Linking: 2 hours
|
||||
- CLI polish: 2 hours
|
||||
- Testing: 2 hours
|
||||
- **Total: ~15 hours**
|
||||
|
||||
## Dependencies
|
||||
|
||||
- None (independent milestone)
|
||||
|
||||
## References
|
||||
|
||||
- [Logseq daily notes](https://docs.logseq.com/#/page/daily%20notes)
|
||||
- [Obsidian daily notes plugin](https://help.obsidian.md/Plugins/Daily+notes)
|
||||
Reference in New Issue
Block a user