memory-search

SKILL.md

Memory Search Skill

File-backed memory system that allows PopeBot agents to store, search, and retrieve memories across jobs. Inspired by OpenClaw's memory-core plugin.

When to Activate

Activate this skill when:

  • You need to remember information across multiple jobs
  • You want to build a knowledge base that persists between sessions
  • You need to search past conversations or decisions
  • You're building agents that learn from experience
  • The user asks to "remember" something or "search memories"

Architecture

┌─────────────────────────────────────────────────────────┐
│  PopeBot Agent                                           │
│  "Remember this pattern" / "What did we learn about X?" │
└─────────────────────┬───────────────────────────────────┘
                      │ Tool calls
┌─────────────────────────────────────────────────────────┐
│  Memory Search Skill                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │ memory_store │  │ memory_search│  │ memory_get   │  │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  │
│         │                 │                 │           │
│         └─────────────────┼─────────────────┘           │
│                           ▼                             │
│              ┌────────────────────────┐                │
│              │  File-based Index      │                │
│              │  - memories/index.json │                │
│              │  - memories/{id}.json  │                │
│              └────────────────────────┘                │
└─────────────────────────────────────────────────────────┘

Commands

Via the memory CLI or tool calls:

Store a Memory

# Store with automatic tagging
memory store "The user prefers TypeScript over JavaScript for new projects"

# Store with custom tags
memory store "API rate limit is 100 requests/minute" --tags api,limits,rate-limiting

# Store with metadata
memory store "Database connection uses SSL on production" --category infrastructure --priority high

Search Memories

# Full-text search
memory search "TypeScript configuration"

# Search by tag
memory search --tag api

# Search by category
memory search --category infrastructure

# Combined search
memory search "rate limit" --tag api --limit 5

# Search with date range
memory search "deployment" --after 2026-01-01 --before 2026-02-25

Get Specific Memory

# Get by ID
memory get mem_abc123

# Get recent memories
memory recent --count 10

# Get memories by tag
memory tagged api,limits

List/Delete Memories

# List all memories
memory list

# List with filters
memory list --tag api --category infrastructure

# Delete a memory
memory delete mem_abc123

# Delete by tag
memory delete --tag obsolete

# Clear all memories (confirmation required)
memory clear --confirm

Tool Calls (Agent Integration)

The skill exposes these tool calls for the Pi agent:

memory_store(content, tags, category, priority)
  - Store a new memory
  - content: string (required) - The memory content
  - tags: string[] (optional) - Tags for categorization
  - category: string (optional) - Category name
  - priority: string (optional) - 'low', 'medium', 'high' (default: 'medium')
  - Returns: { success: true, id: 'mem_abc123', timestamp: '2026-02-25T15:00:00Z' }

memory_search(query, tags, category, limit, after, before)
  - Search memories
  - query: string (optional) - Full-text search query
  - tags: string[] (optional) - Filter by tags
  - category: string (optional) - Filter by category
  - limit: number (optional) - Max results (default: 10)
  - after: string (optional) - ISO date filter
  - before: string (optional) - ISO date filter
  - Returns: { success: true, results: [{ id, content, tags, category, priority, timestamp, relevance }], total: number }

memory_get(id)
  - Get a specific memory by ID
  - id: string (required)
  - Returns: { success: true, memory: { id, content, tags, category, priority, timestamp, metadata } }

memory_recent(count)
  - Get recent memories
  - count: number (optional, default: 10)
  - Returns: { success: true, memories: [...] }

memory_delete(id)
  - Delete a memory
  - id: string (required)
  - Returns: { success: true, deleted: 'mem_abc123' }

memory_list(tags, category, limit)
  - List memories with optional filters
  - tags: string[] (optional)
  - category: string (optional)
  - limit: number (optional, default: 50)
  - Returns: { success: true, memories: [...], total: number }

File Structure

Memories are stored in .pi/memories/:

.pi/memories/
├── index.json           # Search index (tag → memory IDs, category → memory IDs)
├── mem_abc123.json      # Individual memory files
├── mem_def456.json
└── ...

Memory File Format

{
  "id": "mem_abc123",
  "content": "The user prefers TypeScript over JavaScript for new projects",
  "tags": ["preferences", "typescript", "languages"],
  "category": "user-preferences",
  "priority": "medium",
  "timestamp": "2026-02-25T15:00:00Z",
  "metadata": {
    "job_id": "job_abc123",
    "source": "agent",
    "version": 1
  }
}

Index Format

{
  "tags": {
    "typescript": ["mem_abc123", "mem_def456"],
    "api": ["mem_ghi789"]
  },
  "categories": {
    "user-preferences": ["mem_abc123"],
    "infrastructure": ["mem_ghi789"]
  },
  "created_at": "2026-02-25T15:00:00Z",
  "updated_at": "2026-02-25T16:30:00Z"
}

Usage Examples

Example 1: Remember User Preferences

const memory = require('/job/.pi/skills/memory-search/memory.js');

// Store a preference
await memory.store({
  content: "User prefers concise responses with code examples",
  tags: ['preferences', 'communication-style'],
  category: 'user-preferences',
  priority: 'high'
});

// Later, retrieve preferences
const prefs = await memory.search({
  query: 'preferences',
  tags: ['communication-style']
});

Example 2: Build Project Knowledge Base

// Store discoveries during a job
await memory.store({
  content: "The API uses cursor-based pagination with 'next_cursor' field",
  tags: ['api', 'pagination', 'project-knowledge'],
  category: 'project-alpha',
  priority: 'medium'
});

await memory.store({
  content: "Database migrations are in /db/migrations, run with npm run migrate",
  tags: ['database', 'migrations', 'project-knowledge'],
  category: 'project-alpha',
  priority: 'high'
});

// Search for project knowledge
const knowledge = await memory.search({
  tags: ['project-knowledge'],
  category: 'project-alpha'
});

Example 3: Learn from Past Mistakes

// Store a lesson learned
await memory.store({
  content: "Do not use npm install --save, use npm install (saves by default in npm 5+)",
  tags: ['lessons-learned', 'npm', 'mistakes'],
  category: 'best-practices',
  priority: 'high'
});

// Before starting a new task, check for relevant lessons
const lessons = await memory.search({
  query: 'npm install',
  tags: ['lessons-learned']
});

Example 4: Cross-Job Context

// Job 1: Research phase
await memory.store({
  content: "Competitor analysis: Company X uses React, Company Y uses Vue",
  tags: ['research', 'competitive-analysis'],
  category: 'market-research',
  priority: 'medium'
});

// Job 2: Implementation phase (different job, same memory)
const research = await memory.search({
  tags: ['competitive-analysis'],
  category: 'market-research'
});
// Now the implementation agent knows the competitive landscape

Configuration

Create .pi/memories/config.json (optional):

{
  "maxMemories": 10000,
  "autoTag": true,
  "defaultCategory": "general",
  "defaultPriority": "medium",
  "searchRelevance": {
    "tagMatch": 3,
    "categoryMatch": 2,
    "contentMatch": 1
  },
  "retention": {
    "enabled": false,
    "deleteAfterDays": 90,
    "archiveAfterDays": 30
  }
}

Search Algorithm

The search uses a simple relevance scoring system:

  1. Tag match: +3 points per matching tag
  2. Category match: +2 points if category matches
  3. Content match: +1 point per matching word in content
  4. Priority boost: high=+2, medium=+1, low=+0
  5. Recency bonus: +0.1 points per day within last 7 days

Results are sorted by relevance score (descending).

Installation

# Activate the skill
cd /job/.pi/skills
ln -s ../../pi-skills/memory-search memory-search

# Install dependencies
cd memory-search
npm install

Dependencies

{
  "natural": "^6.0.4",
  "node-fetch": "^3.3.2"
}

Testing

# Run test suite
node /job/.pi/skills/memory-search/test.js

# Run integration test
node /job/.pi/skills/memory-search/test.js --integration

When to Use

  • Building agents that need long-term memory
  • Projects spanning multiple jobs
  • Learning from past mistakes and successes
  • Storing user preferences
  • Building knowledge bases
  • Cross-session context sharing

When NOT to Use

  • Single-job tasks with no future relevance
  • Storing sensitive credentials (use GitHub Secrets)
  • Large binary data (use file storage instead)
  • Real-time data that changes frequently

Security Considerations

  • Memories are stored in plaintext files (not encrypted)
  • Do not store passwords, API keys, or sensitive data
  • Memory files are included in git by default (can be gitignored)
  • Consider adding .pi/memories/ to .gitignore for sensitive projects

Troubleshooting

Issue Solution
Memory not found Check memory ID format (mem_xxxxxx)
Search returns no results Try broader query or check tag spelling
Index out of sync Run memory rebuild-index
Memory file corrupted Check JSON syntax in memory file

Future Enhancements

  • Vector search with embeddings
  • Memory compression/archiving
  • Cross-agent memory sharing
  • Memory expiration
  • Memory versioning
  • SQLite backend option

Credits

Inspired by OpenClaw's memory-core plugin. Reimplemented for PopeBot with enhanced search and CLI interface.

Weekly Installs
4
First Seen
14 days ago
Installed on
opencode4
gemini-cli4
claude-code4
github-copilot4
codex4
kimi-cli4