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:
Elliot Chen
2026-06-05 22:35:51 +08:00
commit 518b8eca85
636 changed files with 160553 additions and 0 deletions

View 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.

View 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

View 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.

View 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.

View 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

View 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();

View 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.