# CLAUDE.md

This file provides guidance to Claude Code when working with the OpenClaw package inside the Basic Memory monorepo.

## Project Overview

`@basicmemory/openclaw-basic-memory` is a TypeScript OpenClaw plugin that integrates [Basic Memory](https://github.com/basicmachines-co/basic-memory) with the OpenClaw agent framework. It lives under `integrations/openclaw/` in the monorepo, manages a persistent MCP stdio session to a `bm mcp` process, exposes 14 agent tools (including workspace/project management and cross-project operations), composited memory search/get providers, slash commands, CLI commands, and optional auto-capture of conversations.

## Development Commands

```bash
# Install dependencies (uses Bun)
bun install

# Run all unit tests (Bun native test runner)
bun test

# Run a single test file
bun test tools/search-notes.test.ts

# Integration tests (requires basic-memory CLI installed)
bun run test:int

# Type checking (no emit)
bun run check-types

# Lint (Biome)
bun run lint

# Lint + auto-fix
bun run lint:fix

# All quality checks (fetch skills + type-check + lint + build + tests)
just check

# Release readiness (check + npm pack dry-run)
just release-check
```

## Architecture

### Plugin Lifecycle (`index.ts`)

The default export is an OpenClaw plugin object (`id: "openclaw-basic-memory"`, `kind: "memory"`). The `register(api)` function:

1. Parses config via `parseConfig()` from `config.ts`
2. Creates a `BmClient` instance (the MCP stdio client)
3. Registers all tools, providers, hooks, commands, and the service lifecycle
4. The service `start()` launches the MCP process (`bm mcp --transport stdio`), ensures the project exists, and sets the workspace directory
5. The service `stop()` tears down the MCP connection

### MCP Client (`bm-client.ts` — largest file, ~675 lines)

Central orchestration layer that:
- Spawns and manages a **persistent** `bm mcp --transport stdio` child process via `@modelcontextprotocol/sdk`
- Validates 15 required MCP tools at connect time
- Implements reconnection with bounded retries (500ms, 1s, 2s exponential backoff)
- Distinguishes recoverable errors (broken pipe, transport closed) from fatal errors
- All tool calls require `output_format: "json"` and extract `structuredContent.result`
- Public methods: `search`, `readNote`, `writeNote`, `editNote`, `deleteNote`, `moveNote`, `buildContext`, `recentActivity`, `indexConversation`, `ensureProject`, `listProjects`, `listWorkspaces`, `schemaValidate`, `schemaInfer`, `schemaDiff`
- All content methods accept an optional `project` parameter for cross-project operations
- `listProjects` accepts an optional `workspace` parameter for workspace-scoped listing

### Tools (`tools/`)

Each tool file exports a function that calls `api.registerTool()` with a TypeBox schema and handler. Tools delegate to `BmClient` methods and return OpenClaw-standard responses (`{ content: [{type: "text", text}], details? }`).

- `search-notes.ts`, `read-note.ts`, `write-note.ts`, `edit-note.ts`, `delete-note.ts`, `move-note.ts`, `build-context.ts`, `list-memory-projects.ts`, `list-workspaces.ts`, `schema-validate.ts`, `schema-infer.ts`, `schema-diff.ts` — thin wrappers around `BmClient`; all content tools accept an optional `project` param for cross-project operations
- `memory-provider.ts` — composited `memory_search` + `memory_get` providers. `memory_search` queries 3 sources in parallel: MEMORY.md (grep), BM knowledge graph (FTS + vector), and active task notes (YAML frontmatter scan)

### Commands & Hooks

- `commands/slash.ts` — `/remember` and `/recall` slash commands
- `commands/cli.ts` — `openclaw basic-memory <subcommand>` CLI registration
- `hooks/capture.ts` — auto-capture hook on `agent_end` events, writes timestamped daily conversation notes

### Configuration (`config.ts`)

Flexible config with defaults, snake_case aliases (`memory_dir`/`memory_file`), tilde/relative/absolute path resolution, and unknown-key validation. Cloud routing is configured through `bm cloud` and per-project BM settings, not plugin config.

## Key Patterns

- **TypeBox schemas** (`@sinclair/typebox`) for all tool parameter validation
- **Bun-native test runner** with `describe`/`it`/`expect` and `jest.fn()` mocking
- **ES modules** (`"type": "module"` in package.json)
- **Biome** for linting and formatting (configured in `biome.json`)
- **Build output** — `bun run build` emits `dist/` for `runtimeExtensions`; TypeScript source also stays in the package for source-compatible hosts
- **Strict TypeScript** with `noEmit` (type-checking only)

## Testing

- Unit tests live alongside source files (`*.test.ts`) and mock `BmClient` / `OpenClawPluginApi`
- Integration tests in `integration/` launch a real `bm mcp` process against a temp project
- `scripts/bm-local.sh` runs BM from the monorepo root via `uv run --project ...` when available, then falls back to `bm` on PATH

## CI/CD

- **Package CI** (root `.github/workflows/consolidated-packages.yml`): validates skills, typechecks, lints, builds, tests, and runs `npm pack --dry-run`.
- **Release** (root `.github/workflows/release.yml`): runs from Basic Memory tags and publishes this npm package after the Python release job. Version bumps are handled by the root `just release` / `just beta` recipes.

## Dependencies

- **Runtime**: `@modelcontextprotocol/sdk` (MCP client/transport), `@sinclair/typebox` (schema validation)
- **Peer**: `openclaw` (>=2026.5.2)
- **Dev**: `typescript`, `@biomejs/biome`, `@types/node`
- **External**: Basic Memory CLI (`bm`) must be installed separately (Python, installed via `uv`)

---

# Basic Memory Plugin — Agent Instructions

This plugin provides sophisticated knowledge management through Basic Memory's knowledge graph. Use these tools and guidelines to help users build and navigate their persistent knowledge base.

## Cross-Project Operations

All content tools (`search_notes`, `read_note`, `write_note`, `edit_note`, `delete_note`, `move_note`, `build_context`, `schema_validate`, `schema_infer`, `schema_diff`) accept an optional `project` parameter to operate on a different project than the default. Use this when the user needs to work across multiple knowledge bases.

```
# Search in a different project
search_notes(query="meeting notes", project="team-wiki")

# Read a note from another project
read_note(identifier="decisions/auth-strategy", project="backend")

# Write to a shared project
write_note(title="Shared Insight", content="...", folder="insights", project="shared")
```

## Available Tools

### `list_workspaces`
**Purpose**: List all workspaces (personal and organization) accessible to this user
**When to use**: When the user wants to see what workspaces are available, or before filtering projects by workspace
**Returns**: Workspace names, types (personal/organization), roles, and subscription status

**Examples**:
```
list_workspaces()
```

### `list_memory_projects`
**Purpose**: List all Basic Memory projects, optionally filtered by workspace
**When to use**: When the user wants to see available projects, discover projects in a specific workspace, or before cross-project operations
**Returns**: Project names, paths, default status, and workspace metadata

**Examples**:
```
# List all projects
list_memory_projects()

# List projects in a specific workspace
list_memory_projects(workspace="my-organization")
```

### `search_notes`
**Purpose**: Search the knowledge graph for relevant notes, concepts, and connections
**When to use**: When the user asks about topics, seeks information, or you need context for a discussion
**Returns**: Ranked results with titles, content previews, and relevance scores

**Examples**:
```
# User asks "What did we decide about the API design?"
search_notes(query="API design decisions", limit=5)

# Looking for context on a project
search_notes(query="authentication implementation", limit=3)

# Exploring a broad topic
search_notes(query="meeting notes client feedback", limit=10)

# Search in a different project
search_notes(query="API endpoints", project="backend-docs")
```

### `read_note`
**Purpose**: Read full content of specific notes
**When to use**: When search results show relevant notes that need detailed reading, or when you have a specific note identifier
**Returns**: Complete note content with metadata

**Examples**:
```
# Read a note found in search results
read_note(identifier="projects/api-redesign")

# Navigate to a memory URL
read_note(identifier="memory://agents/decisions/auth-strategy")

# Read by exact title
read_note(identifier="Weekly Review 2024-02-01")

# Read raw markdown including YAML frontmatter
read_note(identifier="projects/api-redesign", include_frontmatter=true)

# Read from another project
read_note(identifier="decisions/auth-strategy", project="backend")
```

### `write_note`
**Purpose**: Create new notes in the knowledge graph
**When to use**: When users share important information, make decisions, or want to save insights for later
**Best practices**: Use clear titles, organize in appropriate folders, structure with headings

**Examples**:
```
# Save a decision or insight
write_note(
  title="API Authentication Decision",
  folder="decisions",
  content="""
# API Authentication Decision

## Context
The team discussed authentication options for the new API.

## Decision
We chose JWT tokens with refresh token rotation.

## Reasoning
- Better security than simple JWTs
- Familiar to the team
- Good ecosystem support

## Next Steps
- [ ] Implement JWT middleware
- [ ] Set up token refresh logic
- [ ] Update API documentation
"""
)

# Document a meeting
write_note(
  title="Client Meeting - February 8, 2024",
  folder="meetings",
  content="""
# Client Meeting - February 8, 2024

## Attendees
- John (client)
- Sarah (product)
- Me (engineering)

## Key Points
- Client wants faster search functionality
- Budget approved for additional features
- Timeline moved up to March 15

## Action Items
- [ ] Prototype search improvements
- [ ] Prepare feature estimate
- [ ] Schedule follow-up meeting
"""
)
```

### `edit_note`
**Purpose**: Modify existing notes incrementally
**When to use**: To add updates, fix information, or organize existing content
**Operations**: append, prepend, find_replace, replace_section

**Examples**:
```
# Add an update to an existing note
edit_note(
  identifier="projects/api-redesign",
  operation="append",
  content="""

## Update - February 8, 2024
Authentication implementation is complete. All tests passing.
Next: Deploy to staging environment.
"""
)

# Update a specific section
edit_note(
  identifier="weekly-review",
  operation="replace_section",
  section="## This Week",
  content="""## This Week
- Completed API authentication
- Client meeting went well
- Working on search improvements
- Delayed deployment due to testing issues
"""
)

# Fix a specific detail
edit_note(
  identifier="team-contacts",
  operation="find_replace",
  find_text="sarah@oldcompany.com",
  content="sarah@newcompany.com",
  expected_replacements=1
)
```

### `delete_note`
**Purpose**: Remove notes from the knowledge graph
**When to use**: When content is outdated, duplicated, or no longer needed
**Returns**: Confirmation of deletion

**Examples**:
```
# Remove an old draft
delete_note(identifier="notes/old-draft")

# Clean up test notes
delete_note(identifier="tests/test-1.0")
```

### `move_note`
**Purpose**: Move notes between folders for organization
**When to use**: When reorganizing knowledge, archiving old content, or correcting folder placement
**Returns**: Updated note with new location

**Examples**:
```
# Archive a completed project
move_note(identifier="projects/api-redesign", newFolder="archive/projects")

# Reorganize into a better folder
move_note(identifier="notes/meeting-notes", newFolder="meetings")
```

### `build_context`
**Purpose**: Navigate the knowledge graph through semantic connections
**When to use**: To explore related concepts, find connected information, or build comprehensive understanding
**Returns**: Target note plus related notes with relationship information

**Examples**:
```
# Explore connections around a project
build_context(url="memory://projects/api-redesign", depth=1)

# Deep dive into related concepts
build_context(url="memory://concepts/authentication", depth=2)

# Discover decision context
build_context(url="memory://decisions/database-choice", depth=1)
```

### `schema_validate`
**Purpose**: Validate notes against their Picoschema definitions
**When to use**: When checking note consistency, after schema changes, or when the user wants to audit note quality

**Examples**:
```
# Validate all notes of a type
schema_validate(noteType="person")

# Validate a single note
schema_validate(identifier="notes/john-doe")

# Validate in another project
schema_validate(noteType="meeting", project="team")
```

### `schema_infer`
**Purpose**: Analyze existing notes and suggest a Picoschema definition
**When to use**: When creating a new schema from existing notes, or exploring what structure notes of a type share

**Examples**:
```
schema_infer(noteType="meeting")
schema_infer(noteType="person", threshold=0.5)
```

### `schema_diff`
**Purpose**: Detect drift between a schema definition and actual note usage
**When to use**: When checking if a schema is still accurate, or after adding new fields to notes

**Examples**:
```
schema_diff(noteType="person")
schema_diff(noteType="Task", project="work")
```

## Knowledge Graph Structure

### Understanding the Graph
Basic Memory organizes information as a **semantic knowledge graph** where:
- **Notes** are documents with content, titles, and metadata
- **Observations** are structured insights extracted from notes
- **Relations** connect related concepts, topics, and decisions

### Memory URLs
Use `memory://` URLs to navigate semantically:
- `memory://projects/api-redesign` - Direct reference to a note
- `memory://agents/decisions` - Category of decision-related notes
- `memory://concepts/authentication` - All content related to authentication

### Organizational Patterns

**Recommended folder structure**:
- `projects/` - Project-specific documentation
- `decisions/` - Important decisions and rationale
- `meetings/` - Meeting notes and action items
- `concepts/` - Technical concepts and explanations
- `agent/` - Agent-captured observations and insights
- `weekly/` - Regular review notes

## Writing Best Practices

### Note Structure
Use consistent markdown structure for better organization:

```markdown
# Clear, Descriptive Title

## Context
Background information and current situation.

## Key Points
- Main insights or decisions
- Important details
- Relevant constraints

## Next Steps
- [ ] Specific action items
- [ ] Follow-up tasks
- [ ] Future considerations
```

### Observation Format
When capturing insights, use this structure:

```markdown
## Observations
- [Decision] We chose PostgreSQL over MongoDB for better ACID guarantees
- [Insight] User authentication patterns suggest social login preference
- [Risk] Current deployment process lacks proper rollback mechanism
- [Opportunity] Search performance could improve with better indexing
```

### Linking and Relations
Create connections between notes:
- Reference other notes by title: `As discussed in [[API Design Principles]]`
- Use consistent terminology for better semantic linking
- Tag important concepts with clear labels
- Cross-reference related decisions and implementations

## When to Use Each Tool

### Discover Workspaces and Projects
Use `list_workspaces` and `list_memory_projects` when:
- User asks what workspaces or projects are available
- Before cross-project operations, to confirm project names
- When switching between personal and organization contexts

### Start with Search
**Always begin with `search_notes`** when:
- User asks about any topic
- You need context for a discussion
- Looking for relevant previous decisions
- Exploring what information already exists

### Read for Details
Use `read_note` when:
- Search results show relevant notes that need full content
- Following up on specific references
- User asks for complete information on a known topic
- Exploring context relationships found in search

### Write for Capture
Use `write_note` when:
- User shares important information to remember
- Decisions are made that should be documented
- Meeting notes or insights need to be preserved
- Creating structured documentation

Any "remember/record/save/note this" request maps to a `write_note` (or `edit_note`) call in that same turn — an acknowledgement without the call saves nothing.

### Edit for Updates
Use `edit_note` when:
- Adding updates to existing notes
- Fixing or updating specific information
- Organizing existing content better
- Appending new insights to previous notes

### Context for Exploration
Use `build_context` when:
- Exploring relationships between concepts
- Building comprehensive understanding
- Finding related information user might not know exists
- Navigating complex topic areas

## User Interaction Guidelines

### Be Proactive
- **Search first**: Before answering questions, search the knowledge graph
- **Suggest connections**: Point out related notes and concepts
- **Offer to save**: When users share important info, offer to document it
- **Never claim an unwritten save**: Only say something was saved or recorded after a `write_note`/`edit_note` call returned a result, and cite the `permalink` or `file_path` from that result — never a filename recalled from memory. If you decline to write, say plainly that nothing new was saved
- **Recommend organization**: Help users structure their knowledge well

### Helpful Patterns
```
User: "What did we decide about the database?"
1. Search: search_notes(query="database decision", limit=5)
2. Read relevant: read_note(identifier="decisions/database-choice")
3. Provide answer with context
4. Ask: "Should I add any updates to this decision note?"

User: "I just had a great meeting with the client"
1. Ask for details
2. Offer: "Would you like me to create a meeting note to capture this?"
3. Write: write_note(title="Client Meeting - [date]", ...)
4. Suggest: "I'll also add this to your weekly review notes"
```

### Memory URL Navigation
Help users discover their knowledge:
```
# After finding a note about "API design"
"I found your API design notes. Let me explore related concepts..."
build_context(url="memory://projects/api-design", depth=2)

# Show user what's connected to their decisions
build_context(url="memory://decisions", depth=1)
```

## Working with User Memory Patterns

### Daily/Weekly Reviews
If users maintain review notes, help them:
```
# Update weekly review
edit_note(
  identifier="weekly-review",
  operation="replace_section",
  section="## This Week",
  content="Updated accomplishments and next steps"
)
```

### Project Documentation
Keep project notes current:
```
# Add project updates
edit_note(
  identifier="projects/current-sprint",
  operation="append",
  content="""
## Sprint Review
- Completed authentication
- Started search feature
"""
)
```

### Decision Tracking
Document important decisions:
```
write_note(
  title="Technical Decision: Database Migration Approach",
  folder="decisions",
  content="""
# Database Migration Decision

## Problem
Current SQLite database can't handle increased load.

## Options Considered
1. Upgrade to PostgreSQL
2. Switch to MongoDB
3. Migrate to cloud database

## Decision
PostgreSQL with staged migration.

## Rationale
- Better performance characteristics
- Team expertise exists
- Strong ACID guarantees needed
- Migration path is well-understood
"""
)
```

## Error Handling

### Tool Failures
If Basic Memory tools fail:
1. Check if the Basic Memory service is running
2. Suggest user verify `bm` CLI installation
3. Recommend checking OpenClaw plugin configuration
4. Fall back to built-in memory tools if available

### Search No Results
When searches return empty:
- Try broader terms
- Suggest creating a new note for the topic
- Look for related concepts that might exist
- Offer to help organize information differently

### Note Not Found
When reading fails:
- Verify the identifier exists
- Suggest searching for similar titles
- Offer to create the note if it should exist
- Check for typos in memory URLs

## Integration Tips

### With Other Tools
The knowledge graph complements other tools:
- **Web search**: Save research findings as notes
- **File operations**: Reference files in knowledge notes
- **Calendar**: Link meeting notes to calendar events
- **Task management**: Connect tasks to project notes

### With User Workflows
Support user patterns:
- **Morning review**: Search for yesterday's notes and updates
- **End of day**: Capture insights and plan next steps
- **Weekly planning**: Review project notes and decisions
- **Knowledge sharing**: Help organize information for others

## Privacy and Content Guidelines

### Sensitive Information
- Don't automatically save sensitive data (passwords, personal info)
- Ask before documenting confidential business information
- Respect user preferences for what to capture
- Use appropriate folder organization for different privacy levels

### Content Quality
- Encourage clear, structured writing
- Help users create searchable content
- Suggest consistent terminology and naming
- Promote good information architecture

---

Remember: The knowledge graph becomes more valuable over time. Help users build it systematically and navigate it effectively. Focus on creating connections between ideas and making information easily discoverable.
