chore: initialize EverOS 1.0.0
md-first memory extraction framework for AI agents. Markdown is the single source of truth; SQLite holds state and LanceDB provides the rebuildable vector + BM25 + scalar index. The codebase follows a single-direction DDD layering (entrypoints -> service -> memory -> infra, with component / core / config cross-cutting) enforced by import-linter. Engineering surface: - Coding conventions in .claude/rules/ (path-scoped) and workflows in .claude/skills/ (/commit, /new-branch, /pr). - GitHub Actions CI runs make lint + test + integration; pre-commit mirrors the gates locally (ruff, hygiene hooks, gitlint commit-msg). - Commit messages follow Conventional Commits, enforced by gitlint. - make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
57
use-cases/claude-code-plugin/commands/ask.md
Normal file
57
use-cases/claude-code-plugin/commands/ask.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
description: Ask a question about past work. Searches memories and combines with current context to answer.
|
||||
arguments:
|
||||
- name: question
|
||||
description: The question to answer
|
||||
required: true
|
||||
---
|
||||
|
||||
# EverMem Ask
|
||||
|
||||
Answer a question using **both** memory search results **and** current conversation context.
|
||||
|
||||
## Question
|
||||
{{question}}
|
||||
|
||||
## Instructions
|
||||
|
||||
1. **Search memories** using `evermem_search` MCP tool with relevant keywords. Start with 10 results.
|
||||
|
||||
2. **Evaluate results**:
|
||||
- If memories provide useful context, note what you learned
|
||||
- If more detail needed, search again with different keywords (up to 3 searches)
|
||||
- If no relevant memories found, that's OK - proceed with what you know
|
||||
|
||||
3. **Combine sources** to answer:
|
||||
- Memory search results (past sessions)
|
||||
- Current conversation context (this session)
|
||||
- Your general knowledge (when applicable)
|
||||
|
||||
4. **Be honest about sources**:
|
||||
- "Based on our discussion on [date]..." - when citing memory
|
||||
- "From our current session..." - when citing current context
|
||||
- "I don't have any recorded information about this" - when memories don't help
|
||||
- "Based on general best practices..." - when using general knowledge
|
||||
|
||||
5. **Admit uncertainty**:
|
||||
- If memories are incomplete or unclear, say so
|
||||
- If you're inferring rather than recalling, make that clear
|
||||
- It's better to say "I don't know" than to guess
|
||||
|
||||
## Response Format
|
||||
|
||||
Start with a direct answer, then provide supporting context:
|
||||
|
||||
```
|
||||
[Direct answer to the question]
|
||||
|
||||
**From memories:**
|
||||
- [Relevant points from past sessions, with dates]
|
||||
|
||||
**Current context:**
|
||||
- [Relevant points from this session, if any]
|
||||
|
||||
**Note:** [Any caveats or gaps in knowledge]
|
||||
```
|
||||
|
||||
Now answer the user's question.
|
||||
59
use-cases/claude-code-plugin/commands/debug.md
Normal file
59
use-cases/claude-code-plugin/commands/debug.md
Normal file
@ -0,0 +1,59 @@
|
||||
---
|
||||
description: View EverMem debug logs to troubleshoot memory saving and retrieval issues
|
||||
---
|
||||
|
||||
# EverMem Debug Log Viewer
|
||||
|
||||
View the EverMem debug log to troubleshoot issues.
|
||||
|
||||
## Instructions
|
||||
|
||||
Show the user the recent debug log entries from `/tmp/evermem-debug.log`.
|
||||
|
||||
1. First check if debug mode is enabled by looking for `EVERMEM_DEBUG=1` in the plugin's `.env` file
|
||||
2. Read the last 50 lines of the debug log file
|
||||
3. If the file doesn't exist or is empty, inform the user how to enable debug mode
|
||||
|
||||
## Actions
|
||||
|
||||
1. Check debug mode status:
|
||||
```bash
|
||||
grep "EVERMEM_DEBUG" /path/to/plugin/.env 2>/dev/null || echo "Not configured"
|
||||
```
|
||||
|
||||
2. Show recent logs:
|
||||
```bash
|
||||
tail -50 /tmp/evermem-debug.log 2>/dev/null || echo "No debug log found"
|
||||
```
|
||||
|
||||
3. Format the output for the user, highlighting:
|
||||
- `[inject]` entries for memory retrieval
|
||||
- `[store]` entries for memory saving
|
||||
- Any errors or warnings
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
📋 EverMem Debug Log
|
||||
|
||||
Status: Debug mode [ENABLED/DISABLED]
|
||||
Log file: /tmp/evermem-debug.log
|
||||
|
||||
--- Recent Entries ---
|
||||
[timestamp] [inject] ...
|
||||
[timestamp] [store] ...
|
||||
|
||||
--- Tips ---
|
||||
• Enable debug: Add EVERMEM_DEBUG=1 to .env
|
||||
• Clear log: > /tmp/evermem-debug.log
|
||||
• Live view: tail -f /tmp/evermem-debug.log
|
||||
```
|
||||
|
||||
## Additional Options
|
||||
|
||||
If the user specifies arguments:
|
||||
- `clear` - Clear the debug log
|
||||
- `live` - Show command for live monitoring
|
||||
- `full` - Show more lines (100+)
|
||||
- `inject` - Filter to show only [inject] entries
|
||||
- `store` - Filter to show only [store] entries
|
||||
45
use-cases/claude-code-plugin/commands/help.md
Normal file
45
use-cases/claude-code-plugin/commands/help.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
description: Get help with EverMem plugin setup and available commands
|
||||
---
|
||||
|
||||
EverMem is a memory plugin for Claude Code that automatically stores and retrieves relevant context from your past coding sessions.
|
||||
|
||||
**How it works:**
|
||||
- When you chat with Claude, your conversations are automatically saved to EverMem Cloud
|
||||
- When you start a new session, relevant memories from past sessions are automatically injected into context
|
||||
- You can also manually search your memories using the `/evermem:search` command
|
||||
|
||||
First, check if the API key is configured:
|
||||
|
||||
```bash
|
||||
if [ -z "${EVERMEM_API_KEY:-}" ]; then
|
||||
echo "STATUS: Not configured"
|
||||
echo ""
|
||||
echo "To get started:"
|
||||
echo "1. Visit https://console.evermind.ai/ to get your API key"
|
||||
echo "2. Add to your shell config (~/.zshrc or ~/.bashrc):"
|
||||
echo " export EVERMEM_API_KEY=\"your_api_key_here\""
|
||||
echo "3. Restart Claude Code"
|
||||
else
|
||||
echo "STATUS: Configured"
|
||||
echo "API Key: ${EVERMEM_API_KEY:0:10}..."
|
||||
fi
|
||||
```
|
||||
|
||||
Present the configuration status to the user. If not configured, guide them through the setup steps.
|
||||
|
||||
**Available Commands:**
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/evermem:help` | Show this help message |
|
||||
| `/evermem:search <query>` | Search your memories for specific topics |
|
||||
| `/evermem:hub` | Open the Memory Hub dashboard to visualize and explore memories |
|
||||
| `/evermem:debug` | View debug logs for troubleshooting |
|
||||
| `/evermem:projects` | View your Claude Code projects table |
|
||||
|
||||
**Automatic Features:**
|
||||
- **Memory Retrieved**: When you submit a prompt, relevant memories are automatically retrieved and shown
|
||||
- **Memory Save**: When Claude finishes responding, the conversation is automatically saved to EverMem Cloud
|
||||
|
||||
Share this information with the user in a clear, helpful format.
|
||||
21
use-cases/claude-code-plugin/commands/hub.md
Normal file
21
use-cases/claude-code-plugin/commands/hub.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
description: Open the EverMem Memory Hub to view statistics, search memories, and explore timeline
|
||||
---
|
||||
|
||||
When the user runs this command:
|
||||
|
||||
1. First, start the proxy server in the background using the Bash tool:
|
||||
```bash
|
||||
node "${CLAUDE_PLUGIN_ROOT}/server/proxy.js" &
|
||||
```
|
||||
|
||||
2. Then, construct the Memory Hub URL with the actual API key using Bash:
|
||||
```bash
|
||||
echo "http://localhost:3456/?key=${EVERMEM_API_KEY}"
|
||||
```
|
||||
|
||||
3. Share a simple message with the user like:
|
||||
"Memory Hub server started. Open this URL to view your memories:
|
||||
[the URL from step 2]"
|
||||
|
||||
Do NOT show the bash commands or code blocks to the user. Just run them and share the final URL.
|
||||
71
use-cases/claude-code-plugin/commands/projects.md
Normal file
71
use-cases/claude-code-plugin/commands/projects.md
Normal file
@ -0,0 +1,71 @@
|
||||
---
|
||||
description: View your Claude Code projects tracked by EverMem
|
||||
---
|
||||
|
||||
# EverMem Projects
|
||||
View all Claude Code projects that have been tracked by EverMem.
|
||||
|
||||
## Instructions
|
||||
|
||||
Show the user their projects stored in the local groups.jsonl file.
|
||||
|
||||
1. Read the groups file from the plugin's data directory
|
||||
2. Aggregate entries by groupId (count sessions, find first/last seen)
|
||||
3. Display the project table with statistics
|
||||
4. If no groups file exists, explain that projects are tracked automatically
|
||||
|
||||
## Actions
|
||||
|
||||
Check and read the groups data file:
|
||||
|
||||
```bash
|
||||
GROUPS_FILE="${CLAUDE_PLUGIN_ROOT}/data/groups.jsonl"
|
||||
if [ -f "$GROUPS_FILE" ] && [ -s "$GROUPS_FILE" ]; then
|
||||
cat "$GROUPS_FILE"
|
||||
else
|
||||
echo "NO_GROUPS_FILE"
|
||||
fi
|
||||
```
|
||||
|
||||
**Note:** The file uses JSONL format (one JSON object per line). Each line is a session start event.
|
||||
|
||||
Entry format: `{"keyId":"...","groupId":"...","name":"...","path":"...","timestamp":"..."}`
|
||||
|
||||
- `keyId`: SHA-256 hash (first 12 chars) of the API key - associates projects with accounts
|
||||
- `groupId`: Short identifier (9 chars: project name prefix + path hash)
|
||||
|
||||
Aggregate by `keyId + groupId` when displaying:
|
||||
- Count occurrences = sessionCount
|
||||
- Earliest timestamp = firstSeen
|
||||
- Latest timestamp = lastSeen
|
||||
|
||||
## Output Format
|
||||
|
||||
If projects exist:
|
||||
```
|
||||
📁 Claude Code Projects
|
||||
|
||||
| Project | Group ID | Sessions | Last Active |
|
||||
|---------------------|------------|----------|-------------|
|
||||
| evermem-claude-code | ever8d8d5 | 42 | just now |
|
||||
| my-react-app | myrea1b2c3 | 12 | 2h ago |
|
||||
|
||||
Total: 2 projects
|
||||
```
|
||||
|
||||
If no projects file:
|
||||
```
|
||||
📁 Claude Code Projects
|
||||
|
||||
No projects tracked yet. Projects are automatically recorded when you start Claude Code sessions.
|
||||
|
||||
Each project directory creates a unique group ID for organizing memories.
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Projects are identified by working directory path (hashed to 9-char ID)
|
||||
- Each project has its own memory namespace in EverMem Cloud
|
||||
- The groups.jsonl file is appended by the SessionStart hook
|
||||
- Same project used with different API keys will appear as separate entries
|
||||
- `keyId` is a SHA-256 hash (first 12 chars) of the API key - secure and unique
|
||||
89
use-cases/claude-code-plugin/commands/scripts/search-memories.js
Executable file
89
use-cases/claude-code-plugin/commands/scripts/search-memories.js
Executable file
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Search memories from EverMem Cloud
|
||||
* Usage: node search-memories.js "query string"
|
||||
*/
|
||||
|
||||
import { getConfig, isConfigured } from '../../hooks/scripts/utils/config.js';
|
||||
import { searchMemories, transformSearchResults } from '../../hooks/scripts/utils/evermem-api.js';
|
||||
|
||||
const query = process.argv[2] || '';
|
||||
|
||||
if (!query) {
|
||||
console.log('Usage: /evermem:search <query>');
|
||||
console.log('Example: /evermem:search "how do we handle authentication"');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!isConfigured()) {
|
||||
console.log('Error: EVERMEM_API_KEY not configured');
|
||||
console.log('Set it with: export EVERMEM_API_KEY="your-key"');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const config = getConfig();
|
||||
console.log('Searching EverMem Cloud...\n');
|
||||
console.log(`Query: "${query}"`);
|
||||
console.log(`User: ${config.userId}`);
|
||||
console.log(`Group: ${config.groupId}`);
|
||||
console.log('');
|
||||
|
||||
const apiResponse = await searchMemories(query, {
|
||||
topK: 10,
|
||||
retrieveMethod: 'hybrid'
|
||||
});
|
||||
|
||||
// Debug: show raw API response
|
||||
console.log('--- RAW API RESPONSE ---');
|
||||
console.log(JSON.stringify(apiResponse, null, 2));
|
||||
console.log('--- END RAW RESPONSE ---\n');
|
||||
|
||||
const memories = transformSearchResults(apiResponse);
|
||||
|
||||
if (memories.length === 0) {
|
||||
console.log('No memories found matching your query.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(`Found ${memories.length} memories:`);
|
||||
console.log('='.repeat(70));
|
||||
|
||||
for (let i = 0; i < memories.length; i++) {
|
||||
const m = memories[i];
|
||||
const score = m.score ? `${(m.score * 100).toFixed(1)}%` : 'N/A';
|
||||
const date = new Date(m.timestamp).toLocaleDateString();
|
||||
const time = new Date(m.timestamp).toLocaleTimeString();
|
||||
|
||||
console.log('');
|
||||
console.log(`${i + 1}. [Score: ${score}] ${date} ${time}`);
|
||||
console.log('-'.repeat(70));
|
||||
|
||||
// Word wrap the content
|
||||
const words = m.text.split(' ');
|
||||
let line = '';
|
||||
for (const word of words) {
|
||||
if ((line + ' ' + word).length > 70) {
|
||||
console.log(line.trim());
|
||||
line = word;
|
||||
} else {
|
||||
line += ' ' + word;
|
||||
}
|
||||
}
|
||||
if (line.trim()) {
|
||||
console.log(line.trim());
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('='.repeat(70));
|
||||
|
||||
} catch (error) {
|
||||
console.log(`Error: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
17
use-cases/claude-code-plugin/commands/search.md
Normal file
17
use-cases/claude-code-plugin/commands/search.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
description: Search EverMem for relevant memories from past sessions
|
||||
arguments:
|
||||
- name: query
|
||||
description: The search query to find relevant memories
|
||||
required: true
|
||||
---
|
||||
|
||||
Search EverMem Cloud for memories matching the user's query.
|
||||
|
||||
Run this command to search:
|
||||
|
||||
```bash
|
||||
node "${CLAUDE_PLUGIN_ROOT}/commands/scripts/search-memories.js" "$ARGUMENTS"
|
||||
```
|
||||
|
||||
After the search completes, summarize the key findings for the user. Highlight the most relevant memories and explain how they might be useful for their current work.
|
||||
Reference in New Issue
Block a user