npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dn-inc/openclaw-seahorse

v0.2.2

Published

Seahorse memory plugin for OpenClaw

Readme

Seahorse Memory Plugin for OpenClaw

Drop-in replacement for OpenClaw's built-in memory search, powered by Seahorse.

  • Uploads local memory files (MEMORY.md, memory/**/*.md) to Seahorse Storage
  • Syncs the entire workspace for full semantic search (syncWorkspace: true)
  • Routes memory_search to Seahorse's vector search API
  • Keeps memory_get reading from local files (same as native)

Why Seahorse?

OpenClaw's built-in memory only indexes markdown notes the agent explicitly writes (MEMORY.md and memory/**/*.md). But agents produce far more than markdown — JSON data, YAML configs, PDF reports, images, spreadsheets, and other artifacts accumulate in the workspace over time, invisible to memory search.

With syncWorkspace: true, Seahorse indexes every supported file in the workspace automatically. The agent can semantically search across all of its own output — not just what it remembered to write down. Documents, data files, images, and markup (37 supported extensions) all become searchable through the same memory_search tool, with no API or workflow changes.

Requirements

  • Node.js 20+
  • OpenClaw >= 2026.1.26
  • Seahorse account (Storage + Table tenants)

Quick Start

  1. Install the plugin:
openclaw plugins install @dn-inc/openclaw-seahorse
  1. Get your Storage URL, Table URL, and API key from the Seahorse console, then add to plugins.entries in openclaw.json:
"openclaw-seahorse": {
  "config": {
    "storageUrl": "https://<your-storage-id>.api.seahorse.dnotitia.ai",
    "tableUrl": "https://<your-table-id>.api.seahorse.dnotitia.ai",
    "apiKey": "your-key-here",
    // Optional: search your entire workspace, not just memory files
    "syncWorkspace": true
  }
}

The apiKey field supports ${ENV_VAR} syntax (e.g., "${SEAHORSE_API_KEY}"), or you can omit it entirely and set the SEAHORSE_API_KEY environment variable.

That's it. The plugin auto-syncs your files on startup and watches for changes in real time.

File Sync

The plugin runs a background service (seahorse-sync) that keeps Seahorse Storage in sync:

  • Initial sync: scans files on startup, uploads only changed files
  • Live watch: detects file create/modify/delete via fs.watch (1.5s debounce)
  • Dedup: mtime-based state tracking prevents redundant uploads
  • Delete sync: local file deletion triggers Seahorse Storage deletion

By default, only memory files (MEMORY.md + memory/**/*.md) are synced. Set syncWorkspace: true to sync the entire workspace — all supported files become searchable via memory_search without any tool or API changes.

Supported file extensions (workspace sync):

| Category | Extensions | |----------|-----------| | Documents | .doc, .docx, .hwp, .hwpx, .odg, .odp, .odt, .pdf, .ppt, .pptx, .rtf | | Data | .csv, .json, .ods, .toml, .tsv, .xls, .xlsx, .yaml, .yml | | Images | .bmp, .gif, .jpeg, .jpg, .png, .tif, .tiff, .webp | | Text / Markup | .epub, .htm, .html, .markdown, .md, .text, .txt, .xhtml, .xml |

When workspace sync is enabled, dotfiles/dotdirs (.*) are always excluded. Add further patterns via syncBlacklist:

{
  "storageUrl": "...", "tableUrl": "...", "apiKey": "...",
  "syncWorkspace": true,
  "syncBlacklist": ["node_modules/", "dist/", "*.log", "*.tmp"]
}

Supported blacklist patterns:

| Pattern | Example | Matches | |---------|---------|---------| | "dir/" | "node_modules/" | Directory with that exact name | | "*.ext" | "*.tmp" | Any segment ending with .tmp | | "prefix*" | ".*" | Any segment starting with . (built-in) | | "name" | "Thumbs.db" | Exact filename in any directory |

Storage Layout

All synced files are stored under the openclaw/ prefix in Seahorse Storage (e.g., MEMORY.mdopenclaw/MEMORY.md). This isolates plugin data from other data in the same Seahorse tenant. Search results are mapped back to workspace-relative paths automatically.

Tools

memory_search

Semantic vector search over synced files via Seahorse.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | query | string | Yes | Search query | | maxResults | number | No | Max results (default: topK config) | | minScore | number | No | Min relevance score 0-1 (default: minScore config) |

memory_get

Read a local file by path.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | path | string | Yes | Relative path (e.g., MEMORY.md, memory/notes.md) | | from | number | No | Start line (1-based) | | lines | number | No | Number of lines to read |

By default, allowed paths are MEMORY.md and files under memory/ only. With syncWorkspace: true, any workspace file is accessible (except blacklisted paths).

Config Reference

Layer 0: Connection (required)

| Field | Type | Required | Description | |-------|------|----------|-------------| | storageUrl | string | Yes | Seahorse Storage tenant URL | | tableUrl | string | Yes | Seahorse Table tenant URL | | apiKey | string | No | API key. Auto-reads from SEAHORSE_API_KEY env var if omitted. Supports ${ENV_VAR} syntax. |

Layer 1: Search & Sync Behavior (optional)

These override the OpenClaw-compatible defaults.

| Field | Type | Default | Description | |-------|------|---------|-------------| | topK | number | 6 | Number of results to return | | minScore | number | 0.35 | Minimum relevance score (0-1) | | searchMode | string | "hybrid" | "dense", "sparse", or "hybrid" | | syncWorkspace | boolean | false | Sync entire workspace (not just memory files) | | syncBlacklist | string[] | [] | Additional blacklist patterns for workspace sync (see File Sync) |

Example — return more results with a lower score threshold:

{
  "storageUrl": "...", "tableUrl": "...", "apiKey": "...",
  "topK": 20,
  "minScore": 0.2
}

Layer 2: Seahorse Tuning (optional, advanced)

Fine-grained control over Seahorse search parameters. Omitted values use Seahorse server defaults.

dense — Dense Vector Search

| Field | Type | Default | Description | |-------|------|---------|-------------| | dense.column | string | "dense_vector" | Dense vector column name | | dense.efSearch | number | (server) | HNSW ef_search parameter |

sparse — Sparse (BM25) Search

| Field | Type | Default | Description | |-------|------|---------|-------------| | sparse.column | string | "sparse_vector" | Sparse vector column name | | sparse.b | number | (server: 0.75) | BM25 document length normalization (0-1) | | sparse.k | number | (server: 1.2) | BM25 term frequency saturation |

fusion — Hybrid Fusion

| Field | Type | Default | Description | |-------|------|---------|-------------| | fusion.type | string | "rrf" | Fusion algorithm | | fusion.alpha | number | 0.7 | Dense weight (0-1). Sparse weight = 1 - alpha | | fusion.k | number | (server: 60) | RRF k parameter |

projection

| Field | Type | Default | Description | |-------|------|---------|-------------| | projection | string | "id, text, metadata, distance, score" | SQL projection for returned fields |

Example — dense-only search with custom ef_search:

{
  "storageUrl": "...", "tableUrl": "...", "apiKey": "...",
  "searchMode": "dense",
  "dense": { "efSearch": 200 }
}

Example — hybrid with equal dense/sparse weighting (Seahorse native behavior):

{
  "storageUrl": "...", "tableUrl": "...", "apiKey": "...",
  "fusion": { "alpha": 0.5 }
}

Defaults Comparison: OpenClaw vs Seahorse

The plugin ships with OpenClaw-compatible defaults. The table below shows where these differ from Seahorse server defaults, so you can tune toward Seahorse-native behavior when desired.

| Parameter | Plugin Default | OpenClaw Native | Seahorse Server | Notes | |-----------|---------------|-----------------|-----------------|-------| | Search mode | hybrid | hybrid | (must specify) | OpenClaw uses hybrid by default | | Top K | 6 | 6 | (must specify) | OpenClaw returns 6 results | | Min score | 0.35 | 0.35 | (no server filter) | Client-side filtering | | Fusion alpha | 0.7 | vector 70% | 0.5 | Key difference. OpenClaw weights dense at 70%. Seahorse defaults to 50/50. Set fusion.alpha: 0.5 for Seahorse-native. | | Fusion k | (server) | N/A | 60 | Omitted; server default used | | BM25 b | (server) | N/A | 0.75 | Omitted; server default used | | BM25 k | (server) | N/A | 1.2 | Omitted; server default used | | ef_search | (server) | N/A | (server decides) | Omitted; server default used | | Dense column | dense_vector | N/A | N/A | Must match your Seahorse table schema | | Sparse column | sparse_vector | N/A | N/A | Must match your Seahorse table schema | | Projection | "id, text, metadata, distance, score" | N/A | (must specify) | Requests both distance (dense) and score (hybrid) for proper normalization |

Hybrid (RRF) Score Normalization: In hybrid mode, Seahorse returns raw RRF scores (~0.01-0.03). The plugin normalizes these to a 0-1 scale by dividing by the theoretical maximum (numRankers / (k + 1)), making them compatible with the minScore threshold. With default k=60 and 2 rankers, a raw score of 0.016 becomes ~0.49 after normalization.