chore: import upstream snapshot with attribution
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "agentmemory",
|
||||
"owner": {
|
||||
"name": "Rohit Ghumare",
|
||||
"github": "rohitg00"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "agentmemory",
|
||||
"description": "Persistent memory for AI coding agents -- captures tool usage, compresses via LLM, injects context into future sessions",
|
||||
"source": "./plugin"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "agentmemory",
|
||||
"interface": {
|
||||
"displayName": "agentmemory"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "agentmemory",
|
||||
"source": {
|
||||
"source": "git-subdir",
|
||||
"url": "https://github.com/rohitg00/agentmemory.git",
|
||||
"path": "./plugin",
|
||||
"ref": "main"
|
||||
},
|
||||
"policy": {
|
||||
"installation": "AVAILABLE",
|
||||
"authentication": "ON_INSTALL"
|
||||
},
|
||||
"category": "Memory"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
# =============================================================================
|
||||
# agentmemory configuration
|
||||
# =============================================================================
|
||||
#
|
||||
# Copy this file to `~/.agentmemory/.env` (or to your project root if you
|
||||
# prefer scoped config) and uncomment the lines you want to override.
|
||||
#
|
||||
# Every line is OFF by default — `agentmemory` runs out of the box with no
|
||||
# LLM key, no embedding key, and no API auth. Set keys here only when you
|
||||
# want to enable the corresponding feature.
|
||||
#
|
||||
# Run `npx @agentmemory/agentmemory init` to copy this file into place
|
||||
# automatically. Run `npx @agentmemory/agentmemory doctor` to verify that
|
||||
# the daemon reads the env you expect.
|
||||
#
|
||||
# Defaults shown in comments. Listed in priority order — the first key
|
||||
# present wins on the LLM detection path (see src/config.ts::detectProvider).
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 1. LLM provider — pick ONE
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# Without a provider key, agentmemory runs in noop mode: observations are
|
||||
# indexed via zero-LLM synthetic compression, hybrid search still works,
|
||||
# but LLM-backed summarisation / reflection / consolidation are disabled.
|
||||
# The detection order is OPENAI_API_KEY → MINIMAX_API_KEY → ANTHROPIC_API_KEY
|
||||
# → GEMINI_API_KEY → OPENROUTER_API_KEY → noop.
|
||||
|
||||
# OPENAI_API_KEY=sk-... # Used for OpenAI-compatible embeddings today. PR #307 will extend this to chat completions (DeepSeek, SiliconFlow, vLLM, LM Studio, Ollama via `/v1`).
|
||||
# OPENAI_BASE_URL=https://api.openai.com # Override for OpenAI-compatible providers
|
||||
|
||||
# ANTHROPIC_API_KEY=sk-ant-...
|
||||
# ANTHROPIC_MODEL=claude-sonnet-4-20250514 # Default Anthropic model
|
||||
# ANTHROPIC_BASE_URL=https://api.anthropic.com # Override for Anthropic-compatible proxies / Azure AI Foundry
|
||||
|
||||
# GEMINI_API_KEY=... # Either env name works; GEMINI_API_KEY takes precedence
|
||||
# GOOGLE_API_KEY=... # Alias for GEMINI_API_KEY when set alone (emits a one-time stderr hint)
|
||||
# GEMINI_MODEL=gemini-2.5-flash # Default Gemini model (auto-detected GA model)
|
||||
|
||||
# OPENROUTER_API_KEY=sk-or-...
|
||||
# OPENROUTER_MODEL=anthropic/claude-sonnet-4-20250514
|
||||
|
||||
# MINIMAX_API_KEY=...
|
||||
# MINIMAX_MODEL=MiniMax-M2.7
|
||||
|
||||
# MAX_TOKENS=4096 # Cap LLM completion tokens for compression / summarise calls
|
||||
|
||||
# Outbound LLM / embedding timeout — shared across every raw-fetch provider
|
||||
# (Gemini, OpenRouter, MiniMax, OpenAI LLM, and OpenAI/Cohere/Voyage/OpenRouter
|
||||
# embedding). The OpenAI LLM path also honours the OpenAI-scoped
|
||||
# OPENAI_TIMEOUT_MS alias for back-compat with v0.9.17 (precedence).
|
||||
# AGENTMEMORY_LLM_TIMEOUT_MS=60000 # Default: 60 000 ms (60 s)
|
||||
|
||||
# Opt-in Claude-subscription fallback (spawns @anthropic-ai/claude-agent-sdk
|
||||
# child sessions). Off by default — the agent-sdk fallback can trigger
|
||||
# Stop-hook recursion (#149 follow-up) when invoked from inside Claude Code.
|
||||
# AGENTMEMORY_ALLOW_AGENT_SDK=true
|
||||
|
||||
# FALLBACK_PROVIDERS=anthropic,gemini # Comma-separated chain tried after the primary provider returns an error (e.g. rate limit)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 2. Embedding provider — auto-detected, override via EMBEDDING_PROVIDER
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# Without an embedding key, agentmemory runs in BM25-only mode for hybrid
|
||||
# search. Detection order: EMBEDDING_PROVIDER override → GEMINI_API_KEY →
|
||||
# OPENAI_API_KEY → VOYAGE_API_KEY → COHERE_API_KEY → OPENROUTER_API_KEY →
|
||||
# local (Xenova/all-MiniLM-L6-v2, 384-dim).
|
||||
|
||||
# EMBEDDING_PROVIDER=local # local | openai | voyage | cohere | gemini | openrouter
|
||||
|
||||
# VOYAGE_API_KEY=pa-... # Optimised for code embeddings
|
||||
|
||||
# COHERE_API_KEY=... # General-purpose embeddings
|
||||
|
||||
# Reuses OPENAI_API_KEY / OPENAI_BASE_URL above when EMBEDDING_PROVIDER=openai.
|
||||
# OPENAI_EMBEDDING_MODEL=text-embedding-3-small # Embedding model when EMBEDDING_PROVIDER=openai
|
||||
# OPENAI_EMBEDDING_DIMENSIONS=1536 # Required when the model is not in the known-models table
|
||||
|
||||
# OPENROUTER_EMBEDDING_MODEL=openai/text-embedding-3-small # When EMBEDDING_PROVIDER=openrouter
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 3. Auth & security
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# Bearer-token auth for the REST API + viewer + all integration plugins.
|
||||
# Without a secret, REST endpoints are open on loopback. Set this when
|
||||
# you expose the daemon beyond loopback or run behind a reverse proxy.
|
||||
|
||||
# AGENTMEMORY_SECRET=your-secret-here
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 4. Search tuning
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# BM25_WEIGHT=0.4 # Hybrid search weight for BM25 leg
|
||||
# VECTOR_WEIGHT=0.6 # Hybrid search weight for vector leg
|
||||
# AGENTMEMORY_GRAPH_WEIGHT=0.2 # Graph traversal bonus on smart-search ranking
|
||||
# TOKEN_BUDGET=2000 # Max tokens injected via mem::context per session
|
||||
# MAX_OBS_PER_SESSION=500 # Per-session observation cap before consolidation kicks in
|
||||
# SUMMARIZE_CHUNK_SIZE=400 # When mem::summarize sees a session larger than this, it chunks observations and map-reduces (chunk-summarize → reduce-merge) to stay within the LLM's context window. Default 400 ≈ 50k tokens per chunk at ~110 tok/obs. Native sessions are capped by MAX_OBS_PER_SESSION; chunking primarily matters for bulk-imported jsonl sessions, which bypass that cap.
|
||||
# SUMMARIZE_CHUNK_CONCURRENCY=6 # Parallel chunk LLM calls during chunked summarize. Default 6 fits ~100-chunk sessions under iii's 180s function-invocation timeout at typical ~8s/call. High-throughput providers (Novita, DeepInfra, DeepSeek) commonly allow 100+ concurrent — bump this for very large imported sessions.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 5. Behaviour flags
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# AGENTMEMORY_AUTO_COMPRESS=true # Run LLM compression on every observation batch (requires a provider key). Default off — synthetic compression handles most cases.
|
||||
# AGENTMEMORY_INJECT_CONTEXT=true # Inject recalled memories back into agent prompts (#143). Default off — hooks capture observations but do not modify conversation.
|
||||
# CONSOLIDATION_ENABLED=true # Run the 4-tier consolidation pipeline (memories → semantic → procedural). Default off — opt in once you've measured the LLM cost.
|
||||
# CONSOLIDATION_DECAY_DAYS=30 # Age (days) after which non-reinforced memories decay during consolidation
|
||||
# GRAPH_EXTRACTION_ENABLED=true # Extract concept-graph edges on remember; powers the graph-traversal recall path
|
||||
# GRAPH_EXTRACTION_BATCH_SIZE=8 # Memories per graph-extraction batch
|
||||
# AGENTMEMORY_REFLECT=true # Periodically auto-synthesize lessons from memories
|
||||
# AGENTMEMORY_DROP_STALE_INDEX=true # Drop on-disk BM25 / vector index on startup if dim guard fires (#248). Recovery toggle for stuck-state debugging.
|
||||
# AGENTMEMORY_IMAGE_EMBEDDINGS=true # Enable image embeddings when an image provider is present (experimental).
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 6. CLI / runtime knobs
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# AGENTMEMORY_TOOLS=all # core (7 tools, default) | all (51 tools) — surface exposed to MCP clients
|
||||
# AGENTMEMORY_SLOTS=memory # Comma-separated plugin slot names the CLI should claim
|
||||
# AGENTMEMORY_DEBUG=1 # Trace MCP shim probe + standalone fallback decisions to stderr
|
||||
# AGENTMEMORY_FORCE_PROXY=1 # Skip the MCP shim livez probe and trust AGENTMEMORY_URL (for sandboxed MCP clients that can't reach localhost)
|
||||
# AGENTMEMORY_PROBE_TIMEOUT_MS=2000 # MCP shim livez probe timeout
|
||||
# AGENTMEMORY_URL=http://localhost:3111 # REST base URL — honored by status, doctor, MCP shim
|
||||
# AGENTMEMORY_VIEWER_URL=http://localhost:3113 # Override the viewer URL printed by `agentmemory status`
|
||||
# AGENTMEMORY_EXPORT_ROOT=~/agentmemory-backup # Default destination for `agentmemory export`
|
||||
|
||||
# STANDALONE_MCP=1 # MCP shim only — bypass the worker and run @agentmemory/mcp in-process
|
||||
# STANDALONE_PERSIST_PATH=~/.agentmemory/local.db # Path used by the standalone MCP shim's local fallback store
|
||||
|
||||
# Snapshot exporter — periodic snapshots of state_store + stream_store.
|
||||
# SNAPSHOT_ENABLED=true
|
||||
# SNAPSHOT_DIR=~/.agentmemory/snapshots
|
||||
# SNAPSHOT_INTERVAL=3600 # Seconds between snapshots
|
||||
|
||||
# Team sharing — when set, memories are scoped to (TEAM_ID, USER_ID) tuples.
|
||||
# TEAM_MODE=shared
|
||||
# TEAM_ID=acme
|
||||
# USER_ID=rohit
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 7. Ports
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# III_REST_PORT=3111 # REST API port (also affects viewer at +2)
|
||||
# III_STREAMS_PORT=3112 # Streams API port
|
||||
# III_ENGINE_URL=ws://localhost:49134 # iii-engine WebSocket URL (used by the worker)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 8. iii engine pin
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# agentmemory currently pins iii-engine to v0.11.2 — v0.11.6 introduces a
|
||||
# new sandbox-everything-via-`iii worker add` model that agentmemory
|
||||
# hasn't been refactored for yet. Override with AGENTMEMORY_III_VERSION
|
||||
# only after migrating to the sandbox model manually.
|
||||
|
||||
# AGENTMEMORY_III_VERSION=0.11.2
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 9. Claude Code bridge (opt-in)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# CLAUDE_MEMORY_BRIDGE=true # Mirror compressed memories into Claude Code's CLAUDE.md
|
||||
# CLAUDE_PROJECT_PATH=/path/to/your/project # Required when CLAUDE_MEMORY_BRIDGE=true
|
||||
# CLAUDE_MEMORY_LINE_BUDGET=200 # Lines of memory CLAUDE.md should hold
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 10. Obsidian export (opt-in)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# OBSIDIAN_AUTO_EXPORT=true # Auto-export memories to an Obsidian vault on every consolidation
|
||||
@@ -0,0 +1 @@
|
||||
github: [rohitg00]
|
||||
@@ -0,0 +1,110 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- dependencies
|
||||
- npm
|
||||
commit-message:
|
||||
prefix: deps
|
||||
include: scope
|
||||
groups:
|
||||
minor-and-patch:
|
||||
update-types:
|
||||
- minor
|
||||
- patch
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /website
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- dependencies
|
||||
- npm
|
||||
- website
|
||||
commit-message:
|
||||
prefix: deps(website)
|
||||
include: scope
|
||||
groups:
|
||||
minor-and-patch:
|
||||
update-types:
|
||||
- minor
|
||||
- patch
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /integrations/openclaw
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 5
|
||||
labels:
|
||||
- dependencies
|
||||
- npm
|
||||
- integrations
|
||||
commit-message:
|
||||
prefix: deps(openclaw)
|
||||
include: scope
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /integrations/pi
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 5
|
||||
labels:
|
||||
- dependencies
|
||||
- npm
|
||||
- integrations
|
||||
commit-message:
|
||||
prefix: deps(pi)
|
||||
include: scope
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /integrations/filesystem-watcher
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 5
|
||||
labels:
|
||||
- dependencies
|
||||
- npm
|
||||
- integrations
|
||||
commit-message:
|
||||
prefix: deps(fs-watcher)
|
||||
include: scope
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
time: "06:00"
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 5
|
||||
labels:
|
||||
- dependencies
|
||||
- github-actions
|
||||
commit-message:
|
||||
prefix: ci(deps)
|
||||
include: scope
|
||||
groups:
|
||||
minor-and-patch:
|
||||
update-types:
|
||||
- minor
|
||||
- patch
|
||||
@@ -0,0 +1,46 @@
|
||||
# GHSA Draft: Stored XSS in agentmemory real-time viewer
|
||||
|
||||
**Severity:** Critical · **CVSS 3.1:** 9.6 (`AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L`)
|
||||
**CWE:** [CWE-79 — Improper Neutralization of Input During Web Page Generation](https://cwe.mitre.org/data/definitions/79.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
agentmemory's real-time viewer (default port 3113) rendered user-controlled data — tool outputs, file paths, memory titles, observation content — into HTML using inline `onclick=` event handlers. The viewer's Content Security Policy simultaneously allowed `script-src 'unsafe-inline'`, meaning injected JavaScript would execute in the reader's browser context.
|
||||
|
||||
## Impact
|
||||
|
||||
Any data captured by agentmemory hooks — which includes tool output from Claude Code, Cursor, or any other agent — becomes an XSS vector when the user opens the viewer. An attacker with the ability to influence any captured observation (e.g., by sending a crafted file contents to be read by an agent, or by planting a malicious commit message in a repository) could:
|
||||
|
||||
- Exfiltrate the entire memory store via authenticated requests from the browser
|
||||
- Read `AGENTMEMORY_SECRET` if the viewer was configured with auth
|
||||
- Make requests to arbitrary endpoints on behalf of the viewer user
|
||||
- Modify the DOM to mislead the developer
|
||||
- Pivot to other localhost services on the developer's machine
|
||||
|
||||
The viewer runs on localhost by default but is **reachable from the browser**, so standard same-origin protections don't help.
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
- All inline `on*=` handlers removed from `src/viewer/index.html`
|
||||
- Replaced with delegated `data-action` event handling
|
||||
- CSP switched to a **per-response script nonce** (`script-src 'nonce-<random>'`)
|
||||
- Added `script-src-attr 'none'` to block any inline handler attributes even if injected
|
||||
- Viewer HTML now rendered through `src/viewer/document.ts` which generates a fresh nonce per request
|
||||
|
||||
## Workarounds
|
||||
|
||||
**None.** Users on affected versions should upgrade to 0.8.2 immediately. Do not open `http://localhost:3113` in a browser on affected versions if you suspect any of your captured observations may contain attacker-controlled content.
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
- Reporter: @eng-pf
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf submitted PR #108 with fixes for this and 5 other vulnerabilities.
|
||||
@@ -0,0 +1,57 @@
|
||||
# GHSA Draft: Remote shell script execution in agentmemory CLI startup
|
||||
|
||||
**Severity:** Critical · **CVSS 3.1:** 9.8 (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`)
|
||||
**CWE:** [CWE-494 — Download of Code Without Integrity Check](https://cwe.mitre.org/data/definitions/494.html), [CWE-829 — Inclusion of Functionality from Untrusted Control Sphere](https://cwe.mitre.org/data/definitions/829.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
The agentmemory CLI (`npx @agentmemory/agentmemory`) auto-installed the iii-engine binary by piping a remote shell script into `sh`:
|
||||
|
||||
```ts
|
||||
execSync("curl -fsSL https://install.iii.dev/iii/main/install.sh | sh")
|
||||
```
|
||||
|
||||
This happened automatically on first run if `iii` was not found in `$PATH`. The script was fetched over HTTPS and executed with the permissions of the user running `npx agentmemory`. No checksum verification, no pinned version, no signature check.
|
||||
|
||||
## Impact
|
||||
|
||||
If `install.iii.dev` were ever compromised — via DNS hijack, domain takeover, expired certificate + MITM on an untrusted network, BGP attack, or any other supply chain attack — **every new agentmemory user would execute attacker-controlled shell code** as their own user.
|
||||
|
||||
This is the canonical "curl | sh" supply chain anti-pattern. It affected:
|
||||
- Developers running `npx @agentmemory/agentmemory` for the first time
|
||||
- CI/CD pipelines that installed agentmemory fresh
|
||||
- Docker builds that installed agentmemory as part of an image
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
- Removed `execSync` call entirely from `src/cli.ts`
|
||||
- CLI now uses an existing local `iii` binary if present in `$PATH`
|
||||
- Falls back to Docker Compose (`docker compose up -d`) if Docker is available
|
||||
- Shows manual install instructions if neither iii nor Docker is found:
|
||||
- `cargo install iii-engine`
|
||||
- `docker pull iiidev/iii:latest`
|
||||
- Docs link: https://iii.dev/docs
|
||||
|
||||
## Workarounds
|
||||
|
||||
Users on affected versions should **install iii-engine manually** and run `agentmemory --no-engine` until upgraded:
|
||||
|
||||
```bash
|
||||
cargo install iii-engine
|
||||
npx @agentmemory/agentmemory@0.8.1 --no-engine
|
||||
```
|
||||
|
||||
Then upgrade to 0.8.2 at the earliest opportunity.
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf
|
||||
@@ -0,0 +1,62 @@
|
||||
# GHSA Draft: agentmemory REST and stream services bound to 0.0.0.0 by default
|
||||
|
||||
**Severity:** High · **CVSS 3.1:** 8.1 (`AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L`)
|
||||
**CWE:** [CWE-668 — Exposure of Resource to Wrong Sphere](https://cwe.mitre.org/data/definitions/668.html), [CWE-306 — Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
The default `iii-config.yaml` bound both the REST API (port 3111) and the streams server (port 3112) to `0.0.0.0`, exposing them on every network interface the host could reach. Combined with the fact that `AGENTMEMORY_SECRET` is **unset by default**, this meant any device on the same local network as a running agentmemory instance could read the entire memory store without authentication.
|
||||
|
||||
Affected endpoints included:
|
||||
- `GET /agentmemory/export` — full dump of every captured observation, memory, session, and audit entry
|
||||
- `GET /agentmemory/sessions` — session list
|
||||
- `POST /agentmemory/smart-search` — arbitrary search over all captured content
|
||||
- `POST /agentmemory/observe` — ability to **inject** fake observations
|
||||
- `POST /agentmemory/remember` — ability to plant arbitrary memories
|
||||
- All 109 other REST endpoints
|
||||
|
||||
## Impact
|
||||
|
||||
A developer running agentmemory on a laptop in a coffee shop, office, or conference WiFi effectively published their entire memory store — including captured API keys, file contents, prompts, decisions, and project context — to anyone on the same network.
|
||||
|
||||
Attackers on the same network could:
|
||||
|
||||
1. **Exfiltrate secrets.** `curl http://<victim-ip>:3111/agentmemory/export` downloads everything. Depending on the incompleteness of the secret redaction (see advisory #06), this could include API keys and tokens.
|
||||
2. **Inject memories.** An attacker could `POST /agentmemory/observe` or `/remember` with fake observations, poisoning the memory store so future sessions retrieve attacker-controlled context.
|
||||
3. **Pivot to other services.** The mesh sync endpoint (before the auth fix in advisory #04) accepted peer data from any source.
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
- `iii-config.yaml` now binds REST, streams to `127.0.0.1`
|
||||
- Viewer server already bound to `127.0.0.1`
|
||||
- New `iii-config.docker.yaml` for Docker deployments: containers bind to `0.0.0.0` internally (required for Docker networking) but host port mapping is restricted to `127.0.0.1:port` in `docker-compose.yml`
|
||||
- README and API section documentation updated to note 127.0.0.1 as the default
|
||||
|
||||
## Workarounds
|
||||
|
||||
Users on affected versions should manually edit their `iii-config.yaml` and change the REST and streams `host` values to `127.0.0.1`:
|
||||
|
||||
```yaml
|
||||
modules:
|
||||
- class: modules::api::RestApiModule
|
||||
config:
|
||||
host: 127.0.0.1 # was 0.0.0.0
|
||||
- class: modules::stream::StreamModule
|
||||
config:
|
||||
host: 127.0.0.1 # was 0.0.0.0
|
||||
```
|
||||
|
||||
And set `AGENTMEMORY_SECRET` to a strong random value to protect endpoints even if network exposure is needed.
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf
|
||||
@@ -0,0 +1,47 @@
|
||||
# GHSA Draft: Unauthenticated mesh sync in agentmemory
|
||||
|
||||
**Severity:** High · **CVSS 3.1:** 7.4 (`AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N`)
|
||||
**CWE:** [CWE-306 — Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html), [CWE-862 — Missing Authorization](https://cwe.mitre.org/data/definitions/862.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
agentmemory's mesh federation feature (P2P sync between instances) accepted push/pull requests on its `/agentmemory/mesh/*` endpoints without requiring authentication. The mesh sync function also did not send any `Authorization` header when calling peer instances, meaning the federation protocol was entirely unauthenticated.
|
||||
|
||||
## Impact
|
||||
|
||||
Any attacker who could reach a mesh-enabled agentmemory instance could:
|
||||
|
||||
1. **Push fake memories** via `POST /agentmemory/mesh/receive` — inject attacker-controlled observations, actions, semantic memories, and relations into the target's memory store. This poisons future retrievals and could be used to manipulate what the target's AI agent sees.
|
||||
2. **Pull the entire memory store** via `GET /agentmemory/mesh/export` — download all memories, actions, and graph data marked as mesh-shareable.
|
||||
3. **Chain with advisory #03** — combined with the default `0.0.0.0` binding, mesh endpoints were reachable from any device on the local network without any authentication.
|
||||
|
||||
Mesh is opt-in (requires an explicit peer registration), so this affected only users who had enabled federation. But those users had no authentication at all.
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
- All 5 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured
|
||||
- The `mem::mesh-sync` function now accepts a `meshAuthToken` parameter and **refuses to sync at all** if the token is missing
|
||||
- Outgoing push/pull requests include `Authorization: Bearer <secret>` headers
|
||||
- Server-side, all mesh endpoints check bearer auth via the existing `checkAuth` helper
|
||||
|
||||
## Workarounds
|
||||
|
||||
Users on affected versions who have mesh federation enabled should:
|
||||
1. Set `AGENTMEMORY_SECRET` to a strong random value on **both** peers
|
||||
2. Restart the server
|
||||
3. Upgrade to 0.8.2 at the earliest opportunity
|
||||
|
||||
Users who have **not** enabled mesh federation are not affected by this specific issue, but should still upgrade for the other 5 fixes.
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf
|
||||
@@ -0,0 +1,61 @@
|
||||
# GHSA Draft: Arbitrary filesystem write via Obsidian export in agentmemory
|
||||
|
||||
**Severity:** Medium · **CVSS 3.1:** 6.5 (`AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L`)
|
||||
**CWE:** [CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')](https://cwe.mitre.org/data/definitions/22.html), [CWE-73 — External Control of File Name or Path](https://cwe.mitre.org/data/definitions/73.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
The `POST /agentmemory/obsidian/export` endpoint accepted a `vaultDir` parameter and passed it directly to `mkdir` and `writeFile` calls without any containment check. A caller could set `vaultDir` to any absolute path on the filesystem and agentmemory would create directories and write Markdown files there with the permissions of the process running the server.
|
||||
|
||||
```bash
|
||||
# Example exploit payload (affected versions only)
|
||||
curl -X POST http://localhost:3111/agentmemory/obsidian/export \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"vaultDir": "/etc/cron.d"}'
|
||||
```
|
||||
|
||||
The content written would be agentmemory's exported memories in Markdown format, but an attacker could craft specific memory content beforehand to plant arbitrary files.
|
||||
|
||||
## Impact
|
||||
|
||||
When chained with advisory #03 (default `0.0.0.0` binding) or advisory #04 (unauthenticated mesh), an attacker on the local network could write arbitrary files to any filesystem location the agentmemory process had write access to.
|
||||
|
||||
Possible exploitation paths:
|
||||
- Write to `~/.ssh/authorized_keys` — SSH key injection
|
||||
- Write to `/etc/cron.d/*` — cron job injection (if running as root)
|
||||
- Write to `~/.bashrc` or shell rc files — code execution on next shell
|
||||
- Overwrite any file the process could write to
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
- New `AGENTMEMORY_EXPORT_ROOT` environment variable (default: `~/.agentmemory`)
|
||||
- `vaultDir` now goes through `resolveVaultDir()` in `src/functions/obsidian-export.ts`:
|
||||
- Resolves the path with `path.resolve`
|
||||
- Checks `resolved === root || resolved.startsWith(root + path.sep)`
|
||||
- Returns `null` if the check fails, and the endpoint returns `{ success: false, error: "vaultDir must be inside AGENTMEMORY_EXPORT_ROOT" }`
|
||||
- Default export is confined to `~/.agentmemory/vault`
|
||||
- Tests added in `test/obsidian-export.test.ts` for both the custom-but-valid case and the rejection case
|
||||
|
||||
## Known limitations
|
||||
|
||||
`resolveVaultDir()` performs lexical containment only — it does not call `fs.realpathSync` / `fs.lstatSync`. A pre-existing symlink under `AGENTMEMORY_EXPORT_ROOT` that points outside the root can still be written through. Users who allow untrusted processes to create files inside `AGENTMEMORY_EXPORT_ROOT` should additionally run agentmemory inside a sandbox that forbids symlink creation, or file a follow-up issue requesting symlink-aware containment.
|
||||
|
||||
## Workarounds
|
||||
|
||||
Users on affected versions should:
|
||||
1. **Disable the Obsidian export endpoint** by setting `OBSIDIAN_AUTO_EXPORT=false` (and avoid calling `/agentmemory/obsidian/export` manually)
|
||||
2. Set `AGENTMEMORY_SECRET` so the endpoint requires bearer auth
|
||||
3. Upgrade to 0.8.2
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf
|
||||
@@ -0,0 +1,60 @@
|
||||
# GHSA Draft: Incomplete secret redaction in agentmemory privacy filter
|
||||
|
||||
**Severity:** Medium · **CVSS 3.1:** 6.2 (`AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`)
|
||||
**CWE:** [CWE-532 — Insertion of Sensitive Information into Log File](https://cwe.mitre.org/data/definitions/532.html), [CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor](https://cwe.mitre.org/data/definitions/200.html)
|
||||
**Affected versions:** `< 0.8.2`
|
||||
**Patched version:** `0.8.2`
|
||||
|
||||
## Summary
|
||||
|
||||
agentmemory's privacy filter (`src/functions/privacy.ts`) is supposed to strip API keys, secrets, and bearer tokens from captured observations before they are stored. The filter used regex patterns to detect common token formats. Three modern token formats were missing from the patterns:
|
||||
|
||||
1. **Bearer tokens** — `Authorization: Bearer <token>` headers were not matched, so any captured HTTP request or response that included an Authorization header flowed into the memory store verbatim.
|
||||
2. **OpenAI project keys** — `sk-proj-*` (the dominant OpenAI API key format since mid-2024) was not matched. The existing `sk-[A-Za-z0-9]{20,}` pattern only caught the legacy format.
|
||||
3. **GitHub fine-grained service/user tokens** — `ghs_*` and `ghu_*` were not matched. The existing `ghp_[A-Za-z0-9]{36}` pattern only caught personal access tokens.
|
||||
|
||||
## Impact
|
||||
|
||||
agentmemory's README explicitly claimed "Privacy first — API keys, secrets, and `<private>` tags are stripped before anything is stored." That claim was **false** for three common token formats.
|
||||
|
||||
Users relying on the privacy filter to protect their captured observations had a false sense of security. Tokens matching these three patterns would:
|
||||
|
||||
1. Be captured by `PostToolUse` hooks alongside the rest of the tool output
|
||||
2. Pass through `stripPrivateData()` unmodified
|
||||
3. Be LLM-compressed and stored in the memory KV
|
||||
4. Be exposed to any attacker who could reach the `/agentmemory/export` or `/agentmemory/smart-search` endpoints
|
||||
5. Be included in Obsidian exports, mesh syncs, and CLAUDE.md bridge writes
|
||||
|
||||
When chained with advisory #03 (default `0.0.0.0` binding), this meant network-adjacent attackers could retrieve captured Bearer tokens, OpenAI keys, and GitHub service tokens from the memory store.
|
||||
|
||||
## Patches
|
||||
|
||||
Fixed in **0.8.2**:
|
||||
|
||||
New regex patterns added to `SECRET_PATTERN_SOURCES` in `src/functions/privacy.ts`:
|
||||
|
||||
```ts
|
||||
/Bearer\s+[A-Za-z0-9._\-+/=]{20,}/gi,
|
||||
/sk-proj-[A-Za-z0-9\-_]{20,}/g,
|
||||
/(?:sk|pk|rk|ak)-[A-Za-z0-9][A-Za-z0-9\-_]{19,}/g,
|
||||
/gh[pus]_[A-Za-z0-9]{36,}/g,
|
||||
```
|
||||
|
||||
Three new unit tests in `test/privacy.test.ts` verify each format is now stripped.
|
||||
|
||||
## Workarounds
|
||||
|
||||
Users on affected versions should:
|
||||
1. Avoid having agents read files or API responses containing these token formats
|
||||
2. Use the `<private>` tag around any block containing secrets — that filter was not affected
|
||||
3. Set `AGENTMEMORY_SECRET` to restrict API access
|
||||
4. Upgrade to 0.8.2
|
||||
|
||||
## References
|
||||
|
||||
- Fix PR: [#108](https://github.com/rohitg00/agentmemory/pull/108)
|
||||
- Commit: [`cbaaf4f`](https://github.com/rohitg00/agentmemory/commit/cbaaf4f)
|
||||
|
||||
## Credit
|
||||
|
||||
@eng-pf
|
||||
@@ -0,0 +1,70 @@
|
||||
name: CI
|
||||
|
||||
# `paths-ignore` keeps doc-only / website / README / CHANGELOG churn from
|
||||
# burning runner minutes. Source / config / workflow changes always run.
|
||||
# `workflow_dispatch` gives a manual re-run button for flake debugging.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
- "CHANGELOG.md"
|
||||
- "AGENTS.md"
|
||||
- "ROADMAP.md"
|
||||
- "website/**"
|
||||
- "docs/**"
|
||||
- "assets/**"
|
||||
- "deploy/**/README.md"
|
||||
- "**/*.md"
|
||||
- "**/*.mdx"
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
- "CHANGELOG.md"
|
||||
- "AGENTS.md"
|
||||
- "ROADMAP.md"
|
||||
- "website/**"
|
||||
- "docs/**"
|
||||
- "assets/**"
|
||||
- "deploy/**/README.md"
|
||||
- "**/*.md"
|
||||
- "**/*.mdx"
|
||||
workflow_dispatch:
|
||||
|
||||
# Cancel in-flight PR runs when a force-push lands. Keep push runs to
|
||||
# protect against partial state on main.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
# Don't bail the whole matrix on one cell's failure — we want to
|
||||
# see whether the same failure reproduces across OSes (e.g.
|
||||
# whether a flake is platform-specific or universal).
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Windows held back: test/obsidian-export.test.ts has hardcoded
|
||||
# POSIX paths (`/tmp/...`) that fail on D:\ drive runners.
|
||||
# src/functions/obsidian-export.ts needs os.tmpdir() + path.join
|
||||
# rework before Windows can be added back. Tracked as follow-up.
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
node-version: [20, 22]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
# Two-step install: generate a lockfile in-runner with
|
||||
# --package-lock-only, then install from it with `npm ci`.
|
||||
# Lockfiles are gitignored at the repo level.
|
||||
- run: npm install --package-lock-only --legacy-peer-deps --no-audit --no-fund
|
||||
- run: npm ci --legacy-peer-deps --no-audit --no-fund
|
||||
- run: npm run build
|
||||
- run: npm run skills:check
|
||||
- run: npm test
|
||||
@@ -0,0 +1,124 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
packages:
|
||||
description: "Packages to publish (comma-separated: agentmemory,mcp,fs-watcher)"
|
||||
required: false
|
||||
default: "agentmemory,mcp,fs-watcher"
|
||||
|
||||
# Workflow-level permissions stay minimal — only `contents: read`
|
||||
# is required to check out the repo. `id-token: write` is granted on
|
||||
# the publish job for npm's --provenance Sigstore OIDC mint.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
# Don't persist the GITHUB_TOKEN to .git/config — the
|
||||
# publish steps don't push back to the repo, so the token
|
||||
# only needs to live in memory for this checkout.
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
# Two-step install: generate a lockfile in-runner with
|
||||
# --package-lock-only, then install from it with `npm ci`. Gives a
|
||||
# single deterministic dep graph across build / test / publish
|
||||
# within one job — important because publish uses `--provenance`.
|
||||
# Lockfiles are gitignored at the repo level.
|
||||
- run: npm install --package-lock-only --legacy-peer-deps --no-audit --no-fund
|
||||
- run: npm ci --legacy-peer-deps --no-audit --no-fund
|
||||
- run: npm run build
|
||||
- run: npm test
|
||||
|
||||
- name: Publish @agentmemory/agentmemory
|
||||
run: |
|
||||
if npm view "@agentmemory/agentmemory@$(node -p "require('./package.json').version")" version >/dev/null 2>&1; then
|
||||
echo "Version already published, skipping"
|
||||
else
|
||||
npm publish --provenance --access public
|
||||
fi
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Wait for npm registry propagation
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
for i in $(seq 1 24); do
|
||||
if npm view "@agentmemory/agentmemory@$VERSION" version >/dev/null 2>&1; then
|
||||
echo "Registry propagated after ${i} attempt(s)"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i: not yet available, sleeping 5s..."
|
||||
sleep 5
|
||||
done
|
||||
echo "ERROR: registry never propagated after 2 minutes" >&2
|
||||
exit 1
|
||||
|
||||
- name: Publish @agentmemory/mcp shim
|
||||
working-directory: packages/mcp
|
||||
run: |
|
||||
SHIM_VERSION=$(node -p "require('./package.json').version")
|
||||
if npm view "@agentmemory/mcp@$SHIM_VERSION" version >/dev/null 2>&1; then
|
||||
echo "Shim version already published, skipping"
|
||||
else
|
||||
npm publish --provenance --access public
|
||||
fi
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Wait for @agentmemory/mcp registry propagation
|
||||
working-directory: packages/mcp
|
||||
run: |
|
||||
SHIM_VERSION=$(node -p "require('./package.json').version")
|
||||
for i in $(seq 1 24); do
|
||||
if npm view "@agentmemory/mcp@$SHIM_VERSION" version >/dev/null 2>&1; then
|
||||
echo "Shim propagated after ${i} attempt(s)"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i: not yet available, sleeping 5s..."
|
||||
sleep 5
|
||||
done
|
||||
echo "ERROR: shim never propagated after 2 minutes" >&2
|
||||
exit 1
|
||||
|
||||
- name: Publish @agentmemory/fs-watcher connector
|
||||
working-directory: integrations/filesystem-watcher
|
||||
run: |
|
||||
FSW_VERSION=$(node -p "require('./package.json').version")
|
||||
if npm view "@agentmemory/fs-watcher@$FSW_VERSION" version >/dev/null 2>&1; then
|
||||
echo "fs-watcher version already published, skipping"
|
||||
else
|
||||
npm publish --provenance --access public
|
||||
fi
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Wait for @agentmemory/fs-watcher registry propagation
|
||||
working-directory: integrations/filesystem-watcher
|
||||
run: |
|
||||
FSW_VERSION=$(node -p "require('./package.json').version")
|
||||
for i in $(seq 1 24); do
|
||||
if npm view "@agentmemory/fs-watcher@$FSW_VERSION" version >/dev/null 2>&1; then
|
||||
echo "fs-watcher propagated after ${i} attempt(s)"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i: not yet available, sleeping 5s..."
|
||||
sleep 5
|
||||
done
|
||||
echo "ERROR: fs-watcher never propagated after 2 minutes" >&2
|
||||
exit 1
|
||||
@@ -0,0 +1,31 @@
|
||||
node_modules/
|
||||
dist/
|
||||
*.tsbuildinfo
|
||||
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
*.log
|
||||
.DS_Store
|
||||
.claude/
|
||||
|
||||
plugin/scripts/*.map
|
||||
plugin/scripts/*.d.mts
|
||||
data/
|
||||
!eval/data/
|
||||
!eval/data/**
|
||||
data-*/
|
||||
agentmemory-debug/
|
||||
.gstack/
|
||||
|
||||
# Lock files — never commit (see feedback_no_lockfiles memory)
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
integrations/hermes/__pycache__/
|
||||
|
||||
# Eval reports (transient; published scorecards live in docs/benchmarks/)
|
||||
eval/reports/
|
||||
# LongMemEval download is 278MB; fetched on demand
|
||||
eval/data/longmemeval/
|
||||
@@ -0,0 +1,124 @@
|
||||
# agentmemory — Agent Instructions
|
||||
|
||||
## Architecture
|
||||
|
||||
agentmemory is a persistent memory system for AI coding agents, built on iii-engine's three primitives (Worker/Function/Trigger). Everything goes through `registerFunction`/`registerTrigger`/`sdk.trigger()` — never bypass iii-engine with standalone SQLite or in-process alternatives.
|
||||
|
||||
- **Engine**: iii-sdk (WebSocket to iii-engine on port 49134)
|
||||
- **State**: File-based SQLite via iii-engine's StateModule (`./data/state_store.db`)
|
||||
- **Build**: TypeScript → ESM via tsdown, output to `dist/`
|
||||
- **Test**: vitest (`npm test` excludes integration tests)
|
||||
|
||||
## Consistency Rules
|
||||
|
||||
**When adding or removing MCP tools, you MUST update ALL of the following:**
|
||||
1. `src/mcp/tools-registry.ts` — tool definition + `getAllTools()` array
|
||||
2. `src/mcp/server.ts` — handler case in the `mcp::tools::call` switch
|
||||
3. `src/triggers/api.ts` — REST endpoint registration
|
||||
4. `src/index.ts` — function registration + endpoint count in the log line
|
||||
5. `test/mcp-standalone.test.ts` — tool count assertion
|
||||
6. `README.md` — tool counts (search for "MCP tools")
|
||||
7. `plugin/.claude-plugin/plugin.json` — tool count in description
|
||||
8. `plugin/plugin.json` and `plugin/.mcp.copilot.json` (when present) — tool count or MCP exposure
|
||||
|
||||
**When adding REST endpoints, you MUST update:**
|
||||
1. `src/triggers/api.ts` — endpoint registration
|
||||
2. `src/index.ts` — endpoint count in the log line
|
||||
3. `README.md` — endpoint count (search for "REST endpoints" and "endpoints on port")
|
||||
|
||||
**When bumping version, you MUST update ALL of the following:**
|
||||
1. `package.json` — version field
|
||||
2. `src/version.ts` — VERSION constant and type union
|
||||
3. `src/types.ts` — ExportData version union
|
||||
4. `src/functions/export-import.ts` — supportedVersions set
|
||||
5. `test/export-import.test.ts` — version assertion
|
||||
6. `plugin/.claude-plugin/plugin.json` — version field
|
||||
7. `plugin/plugin.json` (when present) — version field
|
||||
|
||||
**When adding new KV scopes:**
|
||||
1. `src/state/schema.ts` — add to the KV object
|
||||
2. `src/types.ts` — add the corresponding interface
|
||||
|
||||
**When adding new audit operations:**
|
||||
1. `src/types.ts` — add to AuditEntry.operation union type
|
||||
|
||||
## Code Patterns
|
||||
|
||||
### Function Registration
|
||||
```typescript
|
||||
sdk.registerFunction(
|
||||
"mem::your-function",
|
||||
async (data: { ... }) => {
|
||||
// validate inputs
|
||||
// do work via kv.get/kv.set/kv.list
|
||||
// record audit via recordAudit()
|
||||
return { success: true, ... };
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### REST Endpoint Registration
|
||||
```typescript
|
||||
sdk.registerFunction("api::your-endpoint", async (req: ApiRequest) => {
|
||||
const denied = checkAuth(req, secret);
|
||||
if (denied) return denied;
|
||||
const body = req.body as Record<string, unknown>;
|
||||
// validate + whitelist fields (never pass raw body to sdk.trigger)
|
||||
const result = await sdk.trigger({
|
||||
function_id: "mem::your-function",
|
||||
payload: { ... },
|
||||
});
|
||||
return { status_code: 200, body: result };
|
||||
});
|
||||
sdk.registerTrigger({
|
||||
type: "http",
|
||||
function_id: "api::your-endpoint",
|
||||
config: { api_path: "/agentmemory/your-path", http_method: "POST" },
|
||||
});
|
||||
```
|
||||
|
||||
### MCP Tool Handler
|
||||
```typescript
|
||||
case "memory_your_tool": {
|
||||
// validate args with typeof checks
|
||||
// parse CSV args: args.field.split(",").map(t => t.trim()).filter(Boolean)
|
||||
const result = await sdk.trigger({
|
||||
function_id: "mem::your-function",
|
||||
payload: { ... },
|
||||
});
|
||||
return { status_code: 200, body: { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] } };
|
||||
}
|
||||
```
|
||||
|
||||
### Hook Scripts
|
||||
Hook scripts in `src/hooks/` are standalone Node.js scripts (no iii-sdk import). They read JSON from stdin, make HTTP calls to the REST API, and exit. There are two patterns depending on whether Claude Code consumes the script's stdout:
|
||||
|
||||
- **Context-injecting hooks** (`pre-tool-use`, `pre-compact`, `session-start`) write recalled context to stdout for Claude Code to inject. These MUST use `try/catch` with `await fetch(..., { signal: AbortSignal.timeout(N) })` — the script has to wait for the response before exiting, and the timeout is the only bound on hang time.
|
||||
- **Telemetry-only hooks** (`notification`, `post-tool-failure`, `post-tool-use`, `prompt-submit`, `stop`, `session-end`, `subagent-start`, `subagent-stop`, `task-completed`) write nothing to stdout. These MUST use fire-and-forget `fetch(..., { signal: AbortSignal.timeout(N) }).catch(() => {})` paired with `setTimeout(() => process.exit(0), 500).unref()`. The unawaited fetch dispatches the request; the unref'd `setTimeout` force-exits the process after the request has been flushed to the local daemon's socket buffer (~500ms is enough for single-request hooks; use 1500ms for multi-request hooks like `stop` and `session-end` so all fetches have time to start, especially when `AGENTMEMORY_URL` points to a remote daemon). Without the `setTimeout` Node keeps the event loop alive waiting for any in-flight fetch to settle, which means the hook still blocks Claude Code's next-prompt boundary for up to the AbortSignal duration — exactly the bug fire-and-forget is meant to fix.
|
||||
|
||||
## Coding Standards
|
||||
|
||||
- TypeScript, ESM only (`"type": "module"`)
|
||||
- No code comments explaining WHAT — use clear naming instead
|
||||
- Use `fingerprintId()` for content-addressable dedup, `generateId()` for unique IDs
|
||||
- Parallel operations where possible (`Promise.all` for independent kv writes/reads)
|
||||
- Input validation at system boundaries (MCP handlers, REST endpoints)
|
||||
- REST endpoints must whitelist fields — never pass raw request body to `sdk.trigger()`
|
||||
- Use `recordAudit()` for state-changing operations
|
||||
- Timestamps: capture once with `new Date().toISOString()` and reuse
|
||||
|
||||
## Testing
|
||||
|
||||
- All tests must pass before PR: `npm test` (950+ tests)
|
||||
- Mock pattern: `vi.mock("iii-sdk")` with mock `sdk.trigger`, `kv.get/set/list`
|
||||
- Test files go in `test/` with `.test.ts` extension
|
||||
- Follow existing patterns in `test/crystallize.test.ts` for function tests
|
||||
|
||||
## Current Stats (v0.9.16)
|
||||
|
||||
- 53 MCP tools (8 visible by default, `AGENTMEMORY_TOOLS=all` for all)
|
||||
- 128 REST endpoints
|
||||
- 6 MCP resources, 3 MCP prompts
|
||||
- 12 hooks, 15 skills
|
||||
- 50+ iii functions
|
||||
- 950+ tests
|
||||
@@ -0,0 +1,48 @@
|
||||
# Code of Conduct
|
||||
|
||||
agentmemory follows the [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
||||
|
||||
The short version:
|
||||
|
||||
- Be kind. Assume good faith.
|
||||
- Disagree on the idea, not the person.
|
||||
- Harassment — in issues, PRs, discussions, or any other project space — is not tolerated.
|
||||
- Unwelcome behavior gets moderated first by reminder, then by time-out, then by removal.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Reports go to **ghumare64@gmail.com** with subject `agentmemory CoC`. All reports are confidential.
|
||||
|
||||
Responses follow the Covenant's enforcement ladder — correction, warning, temporary ban, permanent ban — and are decided by the project Maintainers listed in [MAINTAINERS.md](./MAINTAINERS.md). Where a Maintainer is a party to the report, that Maintainer recuses.
|
||||
|
||||
### Escalation when no impartial Maintainer is available
|
||||
|
||||
If every listed Maintainer recuses, or if the project is operating with a single Maintainer and the report concerns that Maintainer, the report is forwarded to an external neutral contact for independent adjudication. The current fallback chain, in order:
|
||||
|
||||
1. **Contributor Covenant community ombudsperson** — email `ombudsperson@contributor-covenant.org` (see <https://www.contributor-covenant.org/faq/>).
|
||||
2. **Hosting foundation abuse channel** — when agentmemory is accepted into a foundation (see `GOVERNANCE.md`), reports can be routed to that foundation's conduct committee instead. The current contact will be published here at that time.
|
||||
3. **GitHub Trust & Safety** — for conduct that occurs inside GitHub spaces, the report can also be filed through <https://support.github.com/contact/report-abuse>.
|
||||
|
||||
The external contact receives the original report verbatim (redacted only of third-party PII unrelated to the incident) and decides the enforcement step. The Maintainer body executes whatever enforcement action the external contact recommends. This ensures no report can dead-end because every internal reviewer is conflicted.
|
||||
|
||||
## Scope
|
||||
|
||||
This applies to every project space:
|
||||
|
||||
- GitHub issues, PRs, discussions, and reviews on this repo.
|
||||
- Any official chat channel that gets set up (currently none).
|
||||
- Public representation of the project at conferences, meetups, and on social media.
|
||||
|
||||
## Full text
|
||||
|
||||
Reproduced verbatim from the Contributor Covenant 2.1 for convenience:
|
||||
|
||||
> We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
|
||||
>
|
||||
> We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
||||
|
||||
Full Covenant v2.1 text: <https://www.contributor-covenant.org/version/2/1/code_of_conduct/>
|
||||
|
||||
## Attribution
|
||||
|
||||
Contributor Covenant is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||
@@ -0,0 +1,115 @@
|
||||
# Contributing to agentmemory
|
||||
|
||||
Thanks for taking an interest. This file is the short path from "I have an idea" to "it's in main."
|
||||
|
||||
## Ground rules
|
||||
|
||||
- Apache-2.0 license applies to every contribution.
|
||||
- Sign-off is required on every commit (see [DCO](#developer-certificate-of-origin) below).
|
||||
- Be civil. [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) applies.
|
||||
- No attribution headers ("Generated with Claude Code", "Co-Authored-By: Claude", etc.) in commits or PR descriptions.
|
||||
|
||||
## Before you open an issue
|
||||
|
||||
Search existing issues first:
|
||||
|
||||
- [open issues](https://github.com/rohitg00/agentmemory/issues?q=is%3Aissue+is%3Aopen)
|
||||
- [closed issues](https://github.com/rohitg00/agentmemory/issues?q=is%3Aissue+is%3Aclosed)
|
||||
|
||||
If it's a bug: provide the repro steps, your Node version, OS, agentmemory version (`npm view @agentmemory/agentmemory version`), and what you expected vs. what you saw.
|
||||
|
||||
If it's a feature: describe the user problem before the implementation. "I couldn't X because Y" beats "please add X."
|
||||
|
||||
## Before you open a PR
|
||||
|
||||
1. Fork the repo and create a branch off `main`:
|
||||
- `feat/<short-name>` for features
|
||||
- `fix/<issue-number>-<short-name>` for bug fixes
|
||||
- `docs/<topic>`, `refactor/<topic>`, `chore/<topic>` for the rest
|
||||
2. `npm install` — you need Node >=20.
|
||||
3. `npm run build` — TypeScript must compile clean.
|
||||
4. `npm test` — the full test suite must pass. The one integration test under `test/integration.test.ts` needs a live server on `:3111` and is fine to skip locally.
|
||||
5. Commit with sign-off. Rebase over tiny fixup commits so the history stays readable.
|
||||
|
||||
## Pull request flow
|
||||
|
||||
- Keep PRs small and focused. One logical change per PR.
|
||||
- Write a clear description: what it does, why, and how to verify.
|
||||
- Link the issue the PR resolves (`Fixes #NNN` / `Closes #NNN`).
|
||||
- Expect CodeRabbit to review automatically. Address its comments before asking a human.
|
||||
- Address review feedback in new commits (do not force-push to the same branch). Maintainers may squash on merge.
|
||||
- A maintainer will merge when tests pass, CodeRabbit is green, and any review comments are addressed.
|
||||
|
||||
## Developer Certificate of Origin
|
||||
|
||||
Every commit must carry a `Signed-off-by` trailer stating you have the right to submit the contribution under Apache-2.0. The full text of the DCO is at <https://developercertificate.org>.
|
||||
|
||||
Add it automatically:
|
||||
|
||||
```bash
|
||||
git commit -s -m "feat: your message"
|
||||
```
|
||||
|
||||
PRs with commits lacking sign-off will not merge.
|
||||
|
||||
## Coding style
|
||||
|
||||
- TypeScript strict mode. No `any` unless justified in a comment.
|
||||
- Prettier-compatible formatting (editor on save is fine; no repo-wide hook).
|
||||
- No code comments that restate what the code does. Only write a comment when the *why* is non-obvious — a hidden constraint, an invariant, a workaround for a specific bug.
|
||||
- No dead code, no commented-out imports.
|
||||
- Tests live next to the feature in `test/<feature>.test.ts`. Name the test after the behavior, not the implementation.
|
||||
|
||||
## Subsystems at a glance
|
||||
|
||||
| Directory | What lives here |
|
||||
|-|-|
|
||||
| `src/triggers/api.ts` | Every HTTP endpoint under `/agentmemory/*`. Adding an MCP tool? Add the REST twin here too. |
|
||||
| `src/mcp/` | Standalone MCP server (`@agentmemory/mcp`), tools registry, transport, in-memory KV. |
|
||||
| `src/functions/` | Core memory operations — observe, compress, consolidate, retention, forget, graph, smart-search, export-import, governance. |
|
||||
| `src/hooks/` | The 12 auto-hooks that capture sessions in agents. |
|
||||
| `src/health/` | Liveness + readiness + alert thresholds. |
|
||||
| `src/state/` | KV schema, keyed mutex, access log. |
|
||||
| `integrations/` | First-party plugins: `hermes/`, `openclaw/`, `filesystem-watcher/`. |
|
||||
| `plugin/` | Claude Code plugin (`agentmemory@agentmemory`). |
|
||||
| `website/` | Marketing site (Next.js 16). |
|
||||
| `test/` | Vitest test suite. |
|
||||
|
||||
## Adding an MCP tool
|
||||
|
||||
1. Register the function in `src/functions/<area>.ts`.
|
||||
2. Register the HTTP trigger in `src/triggers/api.ts` with a matching `api_path`.
|
||||
3. Add the tool entry in `src/mcp/tools-registry.ts`.
|
||||
4. Implement in `src/mcp/standalone.ts` if the standalone MCP package should also expose it.
|
||||
5. Write a test under `test/`.
|
||||
6. No CHANGELOG touch in the PR itself — release PRs are the only place CHANGELOG changes.
|
||||
|
||||
## Adding an auto-hook
|
||||
|
||||
1. Add the new `HookType` string to the union in `src/types.ts`.
|
||||
2. Wire the handler in `src/hooks/<hook-name>.ts`.
|
||||
3. Add a Vitest case that fires the hook and asserts the observation gets written.
|
||||
|
||||
## Release process
|
||||
|
||||
Maintainers cut releases. Every bump touches 8 files in lockstep:
|
||||
|
||||
1. `package.json`
|
||||
2. `package-lock.json` (top + `packages[""].version`)
|
||||
3. `plugin/.claude-plugin/plugin.json`
|
||||
4. `packages/mcp/package.json` (self + `~x.y.z` pin on the main package)
|
||||
5. `src/version.ts` (extend the union, assign)
|
||||
6. `src/types.ts` (`ExportData.version` union)
|
||||
7. `src/functions/export-import.ts` (`supportedVersions` Set)
|
||||
8. `test/export-import.test.ts` (assertion)
|
||||
|
||||
Then: CHANGELOG section, PR, merge, tag, GitHub release. The `Publish to npm` workflow picks up the release trigger and publishes `@agentmemory/agentmemory`, `@agentmemory/mcp`, and `@agentmemory/fs-watcher` to npm with provenance.
|
||||
|
||||
## Security issues
|
||||
|
||||
Do not open a public issue for a security report. See [SECURITY.md](./SECURITY.md).
|
||||
|
||||
## Questions
|
||||
|
||||
- Implementation questions: open a GitHub Discussion.
|
||||
- Governance questions: open an issue labeled `governance`. See [GOVERNANCE.md](./GOVERNANCE.md).
|
||||
@@ -0,0 +1,288 @@
|
||||
# Design System Inspired by Lamborghini
|
||||
|
||||
## 1. Visual Theme & Atmosphere
|
||||
|
||||
Lamborghini's website is a cathedral of darkness — a digital stage where jet-black surfaces stretch infinitely and every element emerges from the void like a machine under a spotlight. The page is almost entirely black. Not dark gray, not near-black — true, uncompromising black (`#000000`) that saturates the viewport and refuses to yield. Into this abyss, white type and Lamborghini Gold (`#FFC000`) are deployed with surgical precision, creating a visual language that feels like walking through a nighttime motorsport event where every surface absorbs light except the things that matter.
|
||||
|
||||
The hero is a full-viewport video — dark, cinematic, immersive — showing event footage or vehicle reveals with the Lamborghini bull logo floating ethereally above. The navigation is minimal: a centered bull logo, a "MENU" hamburger on the left, and search/bookmark icons on the right, all rendered in white against the black canvas. There are no borders, no visible nav containers, no background color on the header — just white marks floating in darkness. The overall mood is nocturnal luxury: exclusive, theatrical, and deliberately intimidating. Each section transition is a scroll through darkness into the next revelation.
|
||||
|
||||
Typography is the voice of this darkness. LamboType — a custom Neo-Grotesk typeface created by Character Type and design agency Strichpunkt — is used for everything from 120px uppercase display headlines to 10px micro labels. Its distinctive 12° angled terminals are inspired by the aerodynamic lines of Lamborghini's super sports cars, and its proportions range from Normal to Ultracompressed width. Headlines SHOUT in uppercase at enormous scales with tight line-heights (0.92 at 120px), creating dense blocks of text that feel stamped from steel. The typeface carries hexagonal geometric DNA — constructed from hexagons, three-armed stars, and circles — that echoes throughout the interface in the hexagonal pause button and UI icons. Built on Bootstrap grid with 68 Element Plus/UI components, the technical infrastructure is substantial beneath the theatrical surface.
|
||||
|
||||
**Key Characteristics:**
|
||||
- True black (`#000000`) dominant surfaces with white and gold as the only relief colors
|
||||
- LamboType custom Neo-Grotesk font with 12° angled terminals inspired by aerodynamic car lines
|
||||
- Lamborghini Gold (`#FFC000`) as the sole accent color — used exclusively for primary CTA buttons
|
||||
- All-uppercase display typography at extreme scales (120px, 80px, 54px) with tight line-heights
|
||||
- Full-viewport video heroes with cinematic event/vehicle content
|
||||
- Zero border-radius on buttons — sharp, angular, uncompromising rectangles
|
||||
- Hexagonal motifs in UI elements (pause button, icon system) echoing brand geometry
|
||||
- Bootstrap grid system + Element Plus/UI 68 components underneath
|
||||
- Transparent ghost buttons with white borders at 50% opacity as the secondary CTA pattern
|
||||
|
||||
## 2. Color Palette & Roles
|
||||
|
||||
### Primary
|
||||
- **Lamborghini Gold** (`#FFC000`): The signature accent color — a warm, saturated amber-gold (rgb 255, 192, 0) used exclusively for primary action buttons ("Discover More", "Tickets", "Start Configuration"). The only chromatic color in the entire interface, it ignites against the black canvas like a headlight cutting through night
|
||||
- **Pure White** (`#FFFFFF`): Primary text color on dark surfaces, logo rendering, nav elements, and light-mode button fills — the voice that speaks from the darkness
|
||||
|
||||
### Secondary & Accent
|
||||
- **Dark Gold** (`#917300`): Hover/pressed state for gold buttons — a deep amber (rgb 145, 115, 0) that darkens the gold to signal interaction
|
||||
- **Gold Text** (`#FFCE3E`): Slightly lighter gold variant (rgb 255, 206, 62) used for inline text accents and highlighted labels
|
||||
- **Cyan Pulse** (`#29ABE2`): Electric blue-cyan (rgb 41, 171, 226) appearing as an informational accent and interactive element highlight
|
||||
- **Link Blue** (`#3860BE`): Medium blue (rgb 56, 96, 190) used universally for link hover states across all text colors
|
||||
|
||||
### Surface & Background
|
||||
- **Absolute Black** (`#000000`): The dominant surface color — used for page background, hero sections, header, footer, and most containers
|
||||
- **Charcoal** (`#202020`): Elevated dark surface (rgb 32, 32, 32) — the primary "dark gray" for cards, panels, and text containers sitting above the black canvas
|
||||
- **Dark Iron** (`#181818`): Subtle surface variant (rgb 24, 24, 24) — barely distinguishable from black, used for footer and deep sections
|
||||
- **Overlay Black** (`rgba(0,0,0,0.7)`): Semi-transparent overlay for modals and video dimming
|
||||
- **Near White** (`#F8F8F8`): Rare light surface (rgb 248, 248, 248) for content blocks in white-mode sections
|
||||
- **Mist** (`#E6E6E6`): Light gray surface for secondary light-mode containers
|
||||
|
||||
### Neutrals & Text
|
||||
- **Pure White** (`#FFFFFF`): Primary text on dark backgrounds — headlines, body, nav labels
|
||||
- **Smoke** (`#F5F5F5`): Secondary text on dark surfaces — slightly softer than pure white
|
||||
- **Graphite** (`#494949`): Dark gray text on light surfaces (rgb 73, 73, 73)
|
||||
- **Ash** (`#7D7D7D`): Mid-range gray for muted text, timestamps, and metadata (rgb 125, 125, 125)
|
||||
- **Steel** (`#969696`): Lighter gray for disabled text and subtle labels (rgb 150, 150, 150)
|
||||
- **Slate** (`#666666`): Alternative mid-gray for secondary content
|
||||
- **Iron** (`#555555`): Dark mid-gray for body text variants
|
||||
- **Shadow** (`#313131`): Very dark gray for text on dark surfaces where white is too strong
|
||||
|
||||
### Semantic & Accent
|
||||
- **Cyan Pulse** (`#29ABE2`): Used for informational highlights and interactive feedback
|
||||
- **Link Blue** (`#3860BE`): Universal hover state for all hyperlinks
|
||||
- **Teal Action** (`#1EAEDB`): Button hover background for transparent/ghost variants (rgb 30, 174, 219)
|
||||
|
||||
### Gradient System
|
||||
- No explicit gradients in the color palette — the dark-to-light progression is achieved through surface layering: `#000000` → `#181818` → `#202020` → `#494949` → `#7D7D7D`
|
||||
- Video heroes use natural atmospheric gradients from the content itself
|
||||
- Top-of-page gradient: subtle dark-to-darker fade at the edges of full-bleed imagery
|
||||
|
||||
## 3. Typography Rules
|
||||
|
||||
### Font Family
|
||||
- **Display & UI**: `LamboType`, Roboto, Helvetica Neue, Arial — custom Neo-Grotesk typeface by Character Type for Lamborghini's 2024 brand refresh. Available in widths from Normal to Ultracompressed and weights from Light (300) to Black. Features 12° angled terminals inspired by aerodynamic car geometry, hexagonal construction logic, and support for 200+ languages including Latin, Cyrillic, and Greek
|
||||
- **Fallback/UI**: `Open Sans` — used for some button/form contexts as system fallback
|
||||
- **No italic variants** observed on the marketing site — the brand voice is always upright
|
||||
|
||||
### Hierarchy
|
||||
|
||||
| Role | Size | Weight | Line Height | Letter Spacing | Notes |
|
||||
|------|------|--------|-------------|----------------|-------|
|
||||
| Hero Display | 120px (7.50rem) | 400 | 0.92 | normal | LamboType, uppercase, maximum impact |
|
||||
| Display 2 | 80px (5.00rem) | 400 | 1.13 | normal | LamboType, uppercase, major section titles |
|
||||
| Section Title | 54px (3.38rem) | 400 | 1.19 | normal | LamboType, uppercase |
|
||||
| Sub-section | 40px (2.50rem) | 400 | 1.15 | normal | LamboType, uppercase |
|
||||
| Feature Heading | 27px (1.69rem) | 400 | 1.37 | normal | LamboType, uppercase |
|
||||
| Card Title | 24px (1.50rem) | 400 | — | normal | LamboType |
|
||||
| Body Large | 18px (1.13rem) | 400 | 1.56 | normal | LamboType, mixed case and uppercase variants |
|
||||
| Body / UI | 16px (1.00rem) | 400/700 | 1.50 | normal/0.16px | LamboType, primary body text |
|
||||
| Button Large | 16px (1.00rem) | 400 | 1.50 | normal | Gold CTA buttons |
|
||||
| Button Standard | 14.4px (0.90rem) | 300/700 | 1.00 | 0.14–0.2px | LamboType, uppercase, ghost buttons |
|
||||
| Button Small | 13px (0.81rem) | 300/500 | 1.20 | 0.13–0.2px | LamboType, compact button variant |
|
||||
| Caption | 14px (0.88rem) | 600/700 | 1.14–1.50 | -0.42px | LamboType, uppercase, negative tracking |
|
||||
| Label | 12px (0.75rem) | 400/500 | 1.83 | 0.96px | LamboType, uppercase badges and micro labels |
|
||||
| Micro | 10px (0.63rem) | 400 | 1.00–2.00 | 0.225px | LamboType, uppercase, smallest text |
|
||||
|
||||
### Principles
|
||||
- **ALL-CAPS is the default voice**: Display and feature headings are universally uppercase. This creates a shouting, commanding tone that matches the brand's aggression
|
||||
- **Extreme scale range**: From 120px heroes to 10px micro labels — a 12:1 ratio that creates dramatic visual hierarchy
|
||||
- **Tight line-heights at scale**: Display sizes use 0.92-1.19 line-height, creating dense, compressed blocks of type that feel stamped rather than typeset
|
||||
- **Weight 400 dominates**: Unlike many design systems that use bold for emphasis, Lamborghini's regular weight carries the headlines — the typeface itself is so distinctive it doesn't need weight variation
|
||||
- **Negative tracking on captions**: -0.42px letter-spacing on 14px captions creates a compressed, technical aesthetic
|
||||
- **Positive tracking on micro text**: +0.225px at 10px ensures legibility at the smallest sizes
|
||||
- **Single typeface discipline**: LamboType handles everything — the 12° angled terminals and hexagonal geometry provide visual coherence across all sizes
|
||||
|
||||
## 4. Component Stylings
|
||||
|
||||
### Buttons
|
||||
All buttons use **zero border-radius** — sharp, angular rectangles that echo the aggressive lines of Lamborghini vehicles.
|
||||
|
||||
**Gold Accent CTA** — The primary action:
|
||||
- Default: bg `#FFC000` (Lamborghini Gold), text `#000000`, padding 24px, fontSize 16px, fontWeight 400, borderRadius 0px, no border
|
||||
- Hover: bg `#917300` (Dark Gold), darkens significantly
|
||||
- Class: `btn-accent btn-large`
|
||||
- Used for: "Discover More", "Tickets", "Start Configuration"
|
||||
|
||||
**Transparent Ghost** — The secondary action on dark backgrounds:
|
||||
- Default: bg transparent, text `#FFFFFF`, border 1px solid `#FFFFFF`, padding 16px, opacity 0.5
|
||||
- Hover: bg `#1EAEDB` (Teal Action), text white, opacity 0.7
|
||||
- Focus: bg `#1EAEDB`, border 1px solid `#000000`, outline 2px solid `#000000`
|
||||
- Used for: secondary CTAs on hero sections and dark panels
|
||||
|
||||
**White Filled** — Light-mode primary:
|
||||
- Default: bg `#FFFFFF`, text `#202020`, no border
|
||||
- Used for: CTAs on dark sections where gold isn't appropriate
|
||||
|
||||
**Black Filled** — Dark filled variant:
|
||||
- Default: bg `#000000`, text `#202020`
|
||||
- Used for: Inverted CTA on light sections
|
||||
|
||||
**Gray Neutral** — Subtle action:
|
||||
- Default: bg `#969696`, text `#202020`
|
||||
- Used for: secondary/tertiary actions, badge-like buttons
|
||||
|
||||
### Cards & Containers
|
||||
- Background: `#202020` (Charcoal) on black canvas, or `#000000` on lighter sections
|
||||
- Border: `0px 1px solid #202020` bottom borders for section dividers
|
||||
- Border-radius: 0px (completely sharp corners)
|
||||
- Shadow: minimal, uses overlay opacity for depth
|
||||
- Content: full-bleed photography + overlaid text in white
|
||||
|
||||
### Inputs & Forms
|
||||
- Minimal form presence on the marketing site
|
||||
- Switch elements: border-radius 20px (the only rounded element), border 1px solid `#DDDDDD`
|
||||
- Cookie banner input style: white text on black with `#7D7D7D` borders
|
||||
|
||||
### Navigation
|
||||
- **Desktop**: Centered bull logo, "MENU" hamburger with icon on left, search icon + bookmarks icon on right
|
||||
- **Background**: Transparent (inherits black page background)
|
||||
- **Sticky**: Fixed to top, floats above content
|
||||
- **No visible borders or shadows** — elements float in the darkness
|
||||
- **"MENU" label**: White text at 14px weight 400, uppercase, accompanies hamburger icon
|
||||
- **Hexagonal motifs**: Pause button on hero sections uses hexagonal outline shape
|
||||
|
||||
### Image Treatment
|
||||
- **Hero**: Full-viewport video sections (100vh) with cinematic event/vehicle footage
|
||||
- **Event photography**: Full-bleed aerial shots of Lamborghini Arena events
|
||||
- **Vehicle imagery**: High-contrast studio shots on dark backgrounds, full-width
|
||||
- **Aspect ratios**: Predominantly 16:9 and wider for cinematic feel
|
||||
- **Dark gradient overlays**: Subtle darkening at top/bottom edges of video to ensure text legibility
|
||||
|
||||
### Distinctive Components
|
||||
- **Hexagonal Pause Button**: Video control uses a hexagonal outline (matching the brand's geometric DNA from the typeface), positioned bottom-right of hero sections
|
||||
- **Progress Bar**: Thin white line at bottom of hero sections indicating video/slide progress
|
||||
- **Badge/Tag**: bg `#969696`, text white, padding 8px, fontSize 10px, borderRadius 2px — tiny metallic pills
|
||||
|
||||
## 5. Layout Principles
|
||||
|
||||
### Spacing System
|
||||
- **Base unit**: 8px
|
||||
- **Full scale**: 2px, 4px, 5px, 8px, 10px, 12px, 15px, 16px, 20px, 24px, 32px, 40px, 48px, 56px
|
||||
- **Button padding**: 16px (ghost), 24px (gold accent)
|
||||
- **Section padding**: 48–56px vertical, 40px horizontal
|
||||
- **Small spacing**: 2–5px for fine adjustments (badge padding, border spacing)
|
||||
|
||||
### Grid & Container
|
||||
- **Framework**: Bootstrap grid system (container + row + col)
|
||||
- **Max width**: 1440px (largest breakpoint)
|
||||
- **Columns**: Standard 12-column Bootstrap grid
|
||||
- **Full-bleed**: Hero sections break out of grid to fill viewport edge-to-edge
|
||||
- **Content areas**: Centered within 1200px max-width containers
|
||||
|
||||
### Whitespace Philosophy
|
||||
Lamborghini uses darkness as whitespace. The generous black expanses between content blocks serve the same function as white space in a light design — creating breathing room that elevates each element to the status of exhibit. A model name floating in the middle of a black viewport has the same visual weight as a gallery piece on a white wall. The absence of color IS the design.
|
||||
|
||||
### Border Radius Scale
|
||||
| Value | Context |
|
||||
|-------|---------|
|
||||
| 0px | Default for everything — buttons, cards, containers, images |
|
||||
| 1px | Subtle span elements |
|
||||
| 2px | Badges, close buttons, cookie elements — barely perceptible |
|
||||
| 20px | Toggle switches only — the sole rounded element |
|
||||
|
||||
## 6. Depth & Elevation
|
||||
|
||||
| Level | Treatment | Use |
|
||||
|-------|-----------|-----|
|
||||
| Level 0 (Abyss) | `#000000` flat | Page background, deepest layer |
|
||||
| Level 1 (Surface) | `#181818` or `#202020` | Cards, content panels, elevated sections |
|
||||
| Level 2 (Overlay) | `rgba(0,0,0,0.7)` | Modal backdrops, video dimming |
|
||||
| Level 3 (Fog) | `rgba(0,0,0,0.5)` | Lighter overlays, hover states |
|
||||
| Level 4 (Mist) | `rgba(0,0,0,0.25)` | Subtle depth hints |
|
||||
|
||||
### Shadow Philosophy
|
||||
Lamborghini achieves depth through surface color layering rather than shadows. On a black canvas, traditional drop shadows are invisible — instead, the system creates elevation by shifting from absolute black to progressively lighter dark grays: `#000000` → `#181818` → `#202020` → `#494949`. This "darkness gradient" approach means that elevated elements are literally lighter than their surroundings, inverting the traditional shadow model.
|
||||
|
||||
### Decorative Depth
|
||||
- Full-bleed video provides atmospheric depth through cinematic lighting
|
||||
- The hexagonal pause button floats with a thin white outline stroke
|
||||
- Progress bars at hero section bottoms create a subtle horizon line
|
||||
- No gradients, glows, or blur effects on UI elements — the photography provides all visual richness
|
||||
|
||||
## 7. Do's and Don'ts
|
||||
|
||||
### Do
|
||||
- Use absolute black (`#000000`) as the primary background — never dark gray as a substitute
|
||||
- Apply Lamborghini Gold (`#FFC000`) exclusively for primary CTA buttons — never for decorative purposes
|
||||
- Set all display headings in uppercase with LamboType — the brand voice is always SHOUTING
|
||||
- Use zero border-radius on buttons and cards — sharp angles are non-negotiable
|
||||
- Maintain tight line-heights (0.92–1.19) on display type to create dense, architectural text blocks
|
||||
- Use the transparent ghost button (white border, 50% opacity) as the secondary CTA on dark backgrounds
|
||||
- Let full-viewport video/photography carry emotional weight — UI is infrastructure, not decoration
|
||||
- Reserve hexagonal geometry for UI icons and the video control button
|
||||
- Use weight 400 (regular) for headlines — the typeface is distinctive enough without bold emphasis
|
||||
- Keep the gray palette achromatic — all neutrals are pure gray without color tinting
|
||||
|
||||
### Don't
|
||||
- Introduce additional accent colors beyond gold — the monochrome-plus-gold system is sacred
|
||||
- Apply border-radius to buttons or cards — curved edges contradict the angular vehicle aesthetic
|
||||
- Use LamboType in italic or decorative styles — the brand is always upright and direct
|
||||
- Add gradients to buttons or surfaces — depth comes from surface layering, not blending
|
||||
- Use light backgrounds as the primary canvas — darkness is the default state, light is the exception
|
||||
- Mix lowercase into display headings — the uppercase convention communicates authority and power
|
||||
- Add hover animations with scale or translate — interactions should be color-only (background/opacity shifts)
|
||||
- Use Open Sans for display text — LamboType must handle all visible typography
|
||||
- Create busy layouts with many small elements — Lamborghini's design is about singular, bold statements
|
||||
- Apply shadows to elements — on a black canvas, shadows are meaningless; use surface color shifts instead
|
||||
|
||||
## 8. Responsive Behavior
|
||||
|
||||
### Breakpoints
|
||||
| Name | Width | Key Changes |
|
||||
|------|-------|-------------|
|
||||
| Mobile Small | <425px | Single column, reduced type scale, stacked buttons |
|
||||
| Mobile | 425-576px | Single column, hamburger nav, hero text ~40px |
|
||||
| Tablet Small | 576-768px | 2-column grid begins, padding adjusts |
|
||||
| Tablet | 768-1024px | 2-column layout, expanded hero, vehicle cards side-by-side |
|
||||
| Desktop | 1024-1280px | Full navigation, 3+ column grids, display text at 80px |
|
||||
| Desktop Large | 1280-1440px | Full layout, hero at 120px display, max-width containers |
|
||||
| Wide | >1440px | Content centered, margins expand, hero fills viewport |
|
||||
|
||||
### Touch Targets
|
||||
- Gold CTA buttons: 48px+ minimum height with 24px padding (exceeds WCAG 44×44px)
|
||||
- Ghost buttons: 48px+ with 16px padding
|
||||
- Hamburger menu: large touch target (~48px square)
|
||||
- Hexagonal pause button: approximately 48px diameter
|
||||
|
||||
### Collapsing Strategy
|
||||
- **Navigation**: Always hamburger-based ("MENU" + icon) — no horizontal nav expansion on any breakpoint
|
||||
- **Hero video**: Maintains full-viewport height across all breakpoints, adjusting object-fit
|
||||
- **Display type**: Scales from 120px (desktop) → 80px (tablet) → 54px/40px (mobile)
|
||||
- **Button layout**: Side-by-side on desktop, stacks vertically on mobile
|
||||
- **Grid columns**: 3-column → 2-column → 1-column progression
|
||||
- **Section spacing**: Reduces from 56px → 40px → 24px vertical padding
|
||||
|
||||
### Image Behavior
|
||||
- Hero videos use `object-fit: cover` to maintain cinematic framing at all sizes
|
||||
- Vehicle images scale within their containers with maintained aspect ratios
|
||||
- Event photography crops to viewport width on narrow screens
|
||||
- Background images darken at edges to maintain text contrast on all viewports
|
||||
|
||||
## 9. Agent Prompt Guide
|
||||
|
||||
### Quick Color Reference
|
||||
- Primary CTA: "Lamborghini Gold (#FFC000)"
|
||||
- Background: "Absolute Black (#000000)"
|
||||
- Surface: "Charcoal (#202020)"
|
||||
- Heading text: "Pure White (#FFFFFF)"
|
||||
- Body text: "Ash (#7D7D7D)"
|
||||
- Link hover: "Link Blue (#3860BE)"
|
||||
- Accent: "Cyan Pulse (#29ABE2)"
|
||||
- Border: "Pure White (#FFFFFF) at 50% opacity"
|
||||
|
||||
### Example Component Prompts
|
||||
- "Create a hero section with a full-viewport black background, the model name 'TEMERARIO' in LamboType at 120px uppercase weight 400 white text with 0.92 line-height, centered vertically, with a Lamborghini Gold (#FFC000) 'Discover More' button below — sharp corners, 0px radius, 24px padding, black text"
|
||||
- "Design a transparent ghost button with 1px solid white border at 50% opacity, white text at 14.4px uppercase with 0.2px letter-spacing, padding 16px, on a black background — hover state changes to Teal Action (#1EAEDB) background with 70% opacity"
|
||||
- "Build a navigation bar with zero visible background on absolute black, a centered bull logo, 'MENU' text label with hamburger icon on the left, and search + bookmark icons on the right — all in white, sticky position"
|
||||
- "Create a news card grid on charcoal (#202020) background with white headlines at 27px uppercase, body text in #7D7D7D at 16px, and a white underlined 'Read More' link that turns #3860BE on hover"
|
||||
- "Design a section divider using a 1px solid bottom border in #202020 on a black canvas — the elevation difference is purely through surface color shift, not shadow"
|
||||
|
||||
### Iteration Guide
|
||||
When refining existing screens generated with this design system:
|
||||
1. Focus on ONE component at a time — Lamborghini's system is extreme and every element must feel aggressive
|
||||
2. Reference specific color names and hex codes from this document — the palette has only about 5 active colors
|
||||
3. Use natural language descriptions, not CSS values — "sharp-cut golden rectangle" not "border-radius: 0px; background: #FFC000"
|
||||
4. Describe the desired "feel" alongside specific measurements — "floating in total darkness" communicates the black canvas better than "background: #000000"
|
||||
5. Remember that UPPERCASE IS THE DEFAULT — if text isn't uppercase at display sizes, it probably should be
|
||||
@@ -0,0 +1,88 @@
|
||||
# Governance
|
||||
|
||||
This document describes how decisions are made in the agentmemory project.
|
||||
|
||||
The model here is a near-copy of the [Linux Foundation Minimum Viable Governance (MVG)](https://github.com/todogroup/ospolog/blob/main/governance/minimum-viable-governance.md) pattern, scoped to the project's current single-maintainer reality with a concrete plan to diversify maintainership over the next two release cycles.
|
||||
|
||||
## Mission
|
||||
|
||||
Ship a persistent, local-first memory runtime for AI coding agents that:
|
||||
|
||||
- Requires zero external databases.
|
||||
- Runs under any MCP-compatible client.
|
||||
- Stays compatible with the open [Model Context Protocol](https://modelcontextprotocol.io).
|
||||
- Keeps every user's data on the user's machine by default.
|
||||
|
||||
## Roles
|
||||
|
||||
### Users
|
||||
|
||||
Anyone who runs agentmemory. No process obligation beyond the license. Feedback via [GitHub issues](https://github.com/rohitg00/agentmemory/issues) and [discussions](https://github.com/rohitg00/agentmemory/discussions) is the input channel.
|
||||
|
||||
### Contributors
|
||||
|
||||
Anyone who opens an issue, comments on an issue, opens a pull request, or otherwise helps the project. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the how-to.
|
||||
|
||||
### Maintainers
|
||||
|
||||
A Maintainer has commit access to the repository, responsibility for reviewing PRs, and a vote on project-level decisions. The current list is tracked in [MAINTAINERS.md](./MAINTAINERS.md).
|
||||
|
||||
A Maintainer is expected to:
|
||||
|
||||
- Respond to PRs they are review-owner for within a reasonable window (goal: 3 working days for first comment).
|
||||
- Uphold the [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
|
||||
- Avoid merging their own non-trivial PRs without a second reviewer once the maintainer count is greater than one.
|
||||
- Disclose conflicts of interest (employer, paid relationships to users).
|
||||
|
||||
### Maintainer acceptance process
|
||||
|
||||
A Contributor becomes a Maintainer by:
|
||||
|
||||
1. Sustained, high-signal contributions over the prior 6 months (multiple merged PRs across more than one subsystem, plus review comments on others' PRs).
|
||||
2. A Maintainer nominates the Contributor in a public PR editing `MAINTAINERS.md`.
|
||||
3. The PR stays open for 7 calendar days to collect objections.
|
||||
4. If no standing objection from an existing Maintainer, the PR merges and the new Maintainer is added.
|
||||
|
||||
A Maintainer steps down by opening a PR that moves their entry to the `Emeritus` section. This is always accepted.
|
||||
|
||||
## Decision-making
|
||||
|
||||
### Default: lazy consensus on PRs
|
||||
|
||||
Most decisions happen inside pull requests. A PR merges when any Maintainer approves it and no other Maintainer blocks it. Silence is assent after 72 hours of no objection.
|
||||
|
||||
### Non-PR decisions
|
||||
|
||||
Anything that is not a normal code change — charter changes, governance edits, maintainer additions/removals, project scope, breaking API changes, relicensing — happens in a GitHub Issue labeled `governance` with a proposal in the first comment.
|
||||
|
||||
- Minor scope decisions: rough consensus in the issue thread, captured by a Maintainer in a summary comment.
|
||||
- Formal votes: Maintainers react `+1` / `-1` / `0` to the summary comment. Simple majority of Maintainers with a minimum of two distinct voters carries. If only one Maintainer exists, a 7-day public comment window substitutes for a vote.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
A breaking change to the REST / MCP surface requires:
|
||||
|
||||
1. A tracking issue labeled `breaking` opened at least one minor release cycle ahead of the change.
|
||||
2. A deprecation path in the codebase (warning log, feature flag, or adapter) for at least one minor release.
|
||||
3. The change landing in the CHANGELOG under a clearly marked `Breaking` sub-section.
|
||||
|
||||
## Release process
|
||||
|
||||
Releases follow [Semantic Versioning](https://semver.org). See the [release process](./CONTRIBUTING.md#release-process) in `CONTRIBUTING.md` and the automated `.github/workflows/publish.yml` pipeline for the mechanics.
|
||||
|
||||
## Conflicts of interest
|
||||
|
||||
Maintainers employed by a company that sells a product competing with agentmemory, or by a company whose business depends on agentmemory's roadmap, should disclose that relationship in `MAINTAINERS.md` next to their name. Nothing prohibits such maintainership; transparency is the requirement.
|
||||
|
||||
## Amending this document
|
||||
|
||||
This document changes by PR. Edits follow the Non-PR decisions path above: open a `governance` issue, collect feedback, then open the PR citing the issue.
|
||||
|
||||
## Related documents
|
||||
|
||||
- [LICENSE](./LICENSE) — Apache-2.0
|
||||
- [CONTRIBUTING.md](./CONTRIBUTING.md) — how to contribute
|
||||
- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) — community behavior
|
||||
- [SECURITY.md](./SECURITY.md) — how to report a vulnerability
|
||||
- [MAINTAINERS.md](./MAINTAINERS.md) — who has commit access
|
||||
- [ROADMAP.md](./ROADMAP.md) — where the project is heading
|
||||
@@ -0,0 +1,164 @@
|
||||
# Install agentmemory (agent runbook)
|
||||
|
||||
You are a coding agent. Follow this runbook top to bottom to install agentmemory, wire it into yourself, and verify that persistent memory works. Run each command, check the result against the "Expect" note, then move on. If a step fails, jump to Troubleshooting, and if it still fails, stop and report the step, the exact command, and the error output.
|
||||
|
||||
## What you are installing
|
||||
|
||||
agentmemory is a local memory server for coding agents. It runs on your machine, exposes a REST API on port 3111 and an MCP server, and stores memories on disk under `~/.agentmemory`. It is built on the iii engine, which agentmemory downloads and manages for you as a pinned binary under `~/.agentmemory/bin`. You do not install iii separately.
|
||||
|
||||
Default mode needs no API key and no cloud account. Out of the box it runs hybrid retrieval (BM25 keyword search plus local on-device embeddings), so a full install proves real semantic recall with zero credentials. An LLM provider key is optional and only unlocks richer summaries and auto-injection (see "Optional: richer features").
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js >= 20 and npm. Check with `node -v`.
|
||||
- macOS or Linux for the one-command path. On Windows, use WSL2; native Windows engine setup is manual and `agentmemory connect` is not supported there.
|
||||
- Ports 3111 (REST), 3112 (streams), 3113 (viewer), and 49134 (engine) free. If any are taken, stop whatever is using them before starting (see Troubleshooting).
|
||||
|
||||
## Running non-interactively
|
||||
|
||||
Several commands prompt on a TTY (for example the first-run "install globally?" question). As an agent you usually want no prompts. Either set `CI=1` in the environment for the commands below, or rely on the fact that agentmemory skips all prompts automatically when stdin/stdout are not a TTY. Prompts are also never-nag: once answered they persist and are not asked again. Re-run onboarding any time with `agentmemory --reset`.
|
||||
|
||||
## 1. Install globally
|
||||
|
||||
```bash
|
||||
npm install -g @agentmemory/agentmemory
|
||||
```
|
||||
|
||||
`npm install -g` already fetches the latest published release. If you hit `EACCES` on a system Node install (macOS/Linux), retry with `sudo npm install -g @agentmemory/agentmemory`.
|
||||
|
||||
No-install alternative: skip this step and run the server with `npx -y @agentmemory/agentmemory@latest` everywhere this runbook says `agentmemory`. The `@latest` and `-y` flags matter because npx caches per version and a bare `npx @agentmemory/agentmemory` can serve a stale release.
|
||||
|
||||
Expect: the install completes without errors.
|
||||
|
||||
## 2. Verify the install
|
||||
|
||||
```bash
|
||||
agentmemory --version
|
||||
```
|
||||
|
||||
Expect: a version string is printed. If `command not found`, the global bin is not on `PATH`; use the `npx -y @agentmemory/agentmemory@latest` form instead.
|
||||
|
||||
## 3. Start the server
|
||||
|
||||
The server listens on port 3111 and auto-starts its pinned iii engine on first run (this can take a few seconds the first time while the engine binary is fetched into `~/.agentmemory/bin`). Run it in the background or in a separate terminal so the rest of the runbook can talk to it.
|
||||
|
||||
```bash
|
||||
agentmemory &
|
||||
```
|
||||
|
||||
Or run `agentmemory` in the foreground in a dedicated terminal.
|
||||
|
||||
Wait until it is reachable, then continue:
|
||||
|
||||
```bash
|
||||
curl -fsS http://localhost:3111/agentmemory/livez
|
||||
```
|
||||
|
||||
Expect: a `200` response. Retry for up to ~15 seconds on first run while the engine warms up.
|
||||
|
||||
## 4. Prove recall in one command
|
||||
|
||||
```bash
|
||||
agentmemory demo --serve
|
||||
```
|
||||
|
||||
`--serve` boots the server, seeds three realistic sessions (JWT auth, an N+1 query fix, rate limiting), runs semantic searches against them, prints the results, and tears everything down. No second terminal needed.
|
||||
|
||||
Expect: the demo finds the "N+1 query fix" memory when it searches for "database performance optimization", which keyword matching alone cannot do. Open `http://localhost:3113` while it runs to watch the memory build live.
|
||||
|
||||
## 5. Wire MCP into the calling agent
|
||||
|
||||
Detect which agent is running this runbook, then wire its MCP config:
|
||||
|
||||
```bash
|
||||
agentmemory connect <agent>
|
||||
```
|
||||
|
||||
`connect` merges agentmemory into that agent's MCP config and preserves any existing servers. Supported agent names:
|
||||
|
||||
`claude-code`, `copilot-cli`, `codex`, `cursor`, `gemini-cli`, `opencode`, `cline`, `continue`, `droid`, `hermes`, `openclaw`, `openhuman`, `pi`, `qwen`, `warp`, `zed`, `antigravity`, `kiro`.
|
||||
|
||||
If you cannot tell which agent you are, default to `claude-code`. After wiring, restart the agent or run its MCP reload command (for example `/mcp` in Claude Code) so it picks up the server.
|
||||
|
||||
Expect: the agent now lists agentmemory's tools. With the server running you should see the full set of 53 tools (for example `memory_save`, `memory_smart_search`, `memory_sessions`). If you see only 7 tools, the MCP shim could not reach a server, see Troubleshooting.
|
||||
|
||||
## 6. Install native skills
|
||||
|
||||
```bash
|
||||
npx skills add rohitg00/agentmemory -y
|
||||
```
|
||||
|
||||
This installs the native skills so the agent knows when to call the memory tools, not just that they exist. `connect` makes the tools available; skills teach the agent when to use them.
|
||||
|
||||
Expect: the skills are installed for the detected agent.
|
||||
|
||||
## 7. Verify a save and recall round-trip
|
||||
|
||||
Confirm health first:
|
||||
|
||||
```bash
|
||||
curl -fsS http://localhost:3111/agentmemory/health
|
||||
```
|
||||
|
||||
Expect: a JSON body with an ok status.
|
||||
|
||||
Now write a memory and read it back. If MCP is wired, call the `memory_save` tool followed by `memory_smart_search`. Otherwise use REST directly (note: these are the REST paths, which differ from the MCP tool names):
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3111/agentmemory/remember \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"content":"agentmemory install verification probe","concepts":["install-check"]}'
|
||||
|
||||
curl -X POST http://localhost:3111/agentmemory/smart-search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query":"install verification probe","limit":5}'
|
||||
```
|
||||
|
||||
Expect: the first call returns `201`, the second returns `200` with results that include the probe memory you just saved.
|
||||
|
||||
If `AGENTMEMORY_SECRET` is set in the environment, the REST API requires it. Add `-H "Authorization: Bearer $AGENTMEMORY_SECRET"` to both calls. By default no secret is set and localhost is open.
|
||||
|
||||
## Optional: richer features
|
||||
|
||||
These are off by default because they spend tokens. Enable them only if the user wants them. Put configuration in `~/.agentmemory/.env` (no `export` prefix), then restart the server.
|
||||
|
||||
- `AGENTMEMORY_INJECT_CONTEXT=true` makes the SessionStart and PreToolUse hooks inject past memory into the agent's context automatically. Cost: spends session tokens proportional to tool-call frequency.
|
||||
- `AGENTMEMORY_AUTO_COMPRESS=true` sends each observation to your LLM provider for a richer summary. Cost: spends API tokens proportional to tool-use frequency. Requires a provider key.
|
||||
- Provider key: set one of `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, and similar, in the same file. Without a key, agentmemory stays in zero-LLM mode and still indexes and recalls via BM25 plus local embeddings.
|
||||
|
||||
## Tool surface
|
||||
|
||||
The MCP server exposes 53 tools by default (`--tools all`). Use `--tools core` (or `AGENTMEMORY_TOOLS=core`) for a lean 8-tool set on hosts with tight tool limits. The 8 core tools cover save, recall, consolidate, smart search, sessions, diagnose, lesson save, and reflect.
|
||||
|
||||
## Lifecycle commands
|
||||
|
||||
- `agentmemory status` shows server and engine state.
|
||||
- `agentmemory doctor` runs diagnostics and reports what is misconfigured.
|
||||
- `agentmemory stop` stops the engine this CLI started (`stop --force` bypasses the Docker guard).
|
||||
- `agentmemory upgrade` upgrades agentmemory and the iii runtime, best effort.
|
||||
- `agentmemory --reset` wipes onboarding preferences and re-runs the wizard.
|
||||
- `agentmemory import-jsonl <file>` imports prior Claude Code session logs as memories.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `command not found: agentmemory`: the global bin is not on `PATH`. Use `npx -y @agentmemory/agentmemory@latest`.
|
||||
- `EACCES` during global install: retry with `sudo`, or use the npx form.
|
||||
- Stale npx version: run `npx -y @agentmemory/agentmemory@latest`, or clear the cache with `rm -rf ~/.npm/_npx` (macOS/Linux).
|
||||
- Port already in use: another process holds 3111, 3112, 3113, or 49134. Stop that process, then re-run.
|
||||
- Server starts but `livez` never returns 200: re-run with `agentmemory --verbose` to see engine stderr.
|
||||
- Engine version warning on start: harmless. agentmemory uses its own pinned engine in `~/.agentmemory/bin` regardless of any `iii` on `PATH`. Set `AGENTMEMORY_III_VERSION` only to override deliberately.
|
||||
- "engine conflict" / another iii engine already running: if a different iii version is already serving the port (common if you run your own iii), agentmemory will not adopt it and stops with an "engine conflict" note. Stop that engine (`agentmemory stop --force`, or however you started it), then re-run `agentmemory` — it installs and runs the pinned engine in `~/.agentmemory/bin`, leaving your own iii untouched.
|
||||
- Only 7 tools visible in the agent: the MCP shim is in local fallback because it could not reach a server. Start `npx @agentmemory/agentmemory` and ensure `AGENTMEMORY_URL` points at it (default `http://localhost:3111`), then reload MCP.
|
||||
- Windows: use WSL2 for the path above. Native Windows runs the server but `connect` and the automated engine install are not supported.
|
||||
|
||||
## Report success
|
||||
|
||||
Report back to the user:
|
||||
|
||||
- agentmemory installed, version, and the server running on port 3111
|
||||
- which agent was wired via `agentmemory connect`, and the tool count the agent now sees
|
||||
- the save and recall round-trip returned the probe memory
|
||||
- the viewer is available at `http://localhost:3113`
|
||||
- whether any optional features were enabled
|
||||
|
||||
If any step failed, report which step, the exact command, and the error output.
|
||||
@@ -0,0 +1,190 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2026 Rohit Ghumare
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Maintainers
|
||||
|
||||
The authoritative list of people with commit access. See [GOVERNANCE.md](./GOVERNANCE.md) for what a Maintainer is, what they do, and how someone becomes one.
|
||||
|
||||
## Active
|
||||
|
||||
| Name | GitHub | Affiliation | Area of focus | Since |
|
||||
|-|-|-|-|-|
|
||||
| Rohit Ghumare | [@rohitg00](https://github.com/rohitg00) | Independent | Project lead, all subsystems | 2026-01 |
|
||||
|
||||
## Emeritus
|
||||
|
||||
_None yet._
|
||||
|
||||
## Maintainer recruitment
|
||||
|
||||
agentmemory is actively looking to diversify maintainership. The growth plan in [ROADMAP.md](./ROADMAP.md) commits to adding at least one additional Maintainer from a different organization by the end of the current growth cycle.
|
||||
|
||||
If you have a sustained contribution track record and would like to be considered, open an issue tagged `governance`.
|
||||
|
||||
The complete contributor graph, with commit counts and recent activity, lives at <https://github.com/rohitg00/agentmemory/graphs/contributors>.
|
||||
@@ -0,0 +1,7 @@
|
||||
# WeHub 来源说明
|
||||
|
||||
- 原始项目:`rohitg00/agentmemory`
|
||||
- 原始仓库:https://github.com/rohitg00/agentmemory
|
||||
- 导入方式:上游默认分支的最新快照
|
||||
- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准
|
||||
- 本文件仅用于记录来源,不代表 WeHub 是原项目作者
|
||||
@@ -0,0 +1,92 @@
|
||||
# Roadmap
|
||||
|
||||
This is agentmemory's public 12-month roadmap. It covers Q2 2026 through Q1 2027. The roadmap is the source of truth for where the project is heading; anything significant that lands in main should trace back to an item here or a ratified issue.
|
||||
|
||||
Items shift as evidence changes. Each quarter we publish a short retrospective on what landed, what slipped, and why — attached to the release notes.
|
||||
|
||||
## How to read this
|
||||
|
||||
- **Shipped** — landed in main and tagged in a release.
|
||||
- **Active** — in-flight, has an open PR or issue owner.
|
||||
- **Planned** — accepted scope for the quarter, not started.
|
||||
- **Candidate** — under consideration, may defer.
|
||||
|
||||
Anything not on this list that a contributor wants to pursue is welcome — open an issue labeled `roadmap` and it gets triaged against the quarterly theme.
|
||||
|
||||
## Themes
|
||||
|
||||
- **Q2 2026 — Depth.** Multimodal memory, more connectors, close out backlog from the v0.9 cycle.
|
||||
- **Q3 2026 — Breadth.** Hook parity across more agents, community expansion, OpenSSF best-practices alignment.
|
||||
- **Q4 2026 — Trust.** Enterprise features — SSO, audit export, RBAC, long-running deployment story.
|
||||
- **Q1 2027 — v1.0.** Stability, LTS branch, semver freeze on the REST + MCP surface.
|
||||
|
||||
## Q2 2026 — Depth (April – June)
|
||||
|
||||
### Shipped so far in this quarter
|
||||
- [x] iii console docs in README with vendored screenshots (#157)
|
||||
- [x] Health severity gated on RSS floor (#158 / PR #160)
|
||||
- [x] Standalone MCP proxies to the running server (#159 / PR #161)
|
||||
- [x] Audit coverage for `mem::forget` + audit policy doc (#125 / PR #162)
|
||||
- [x] `@agentmemory/fs-watcher` filesystem connector (#62 / PR #163)
|
||||
- [x] Next.js website on Vercel (PR #164)
|
||||
- [x] CI publishes all three npm packages on release (PR #166)
|
||||
|
||||
### Active
|
||||
- [ ] **Multimodal memory** — content-addressed image store, vision-prompt compression, disk quota + refcount on eviction (#64, PR #111)
|
||||
- [ ] **Governance baseline** — this file, plus `GOVERNANCE.md`, `CONTRIBUTING.md`, `MAINTAINERS.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`
|
||||
|
||||
### Planned
|
||||
- [ ] **GitHub connector** (`@agentmemory/github-watcher`) — sync issues, PRs, discussions as observations. Shares the `POST /agentmemory/observe` wire format with the filesystem connector.
|
||||
- [x] **OpenCode hook bus** (#156) — wired 22 hooks covering all 12 Claude Code hook types: session lifecycle (create/idle/status/compacted/update/diff/delete/error), messages & prompts (chat.message, message.updated user+assistant, message.removed), tool capture (before + rich ToolPart lifecycle in message.part.updated), memory injection (context + enrich via system.transform), part tracking (subtask, step-finish, reasoning, file, patch, compaction, agent, retry), file enrichment pipeline (stash via tool.execute.before + file.edited + file parts), permissions (updated + replied), task tracking (todo.updated w/ priority), commands (command.executed), config & model tracking (config + chat.params). Plus 2 slash commands (recall/remember). See `plugin/opencode/`.
|
||||
- [ ] **Session replay UI** in the real-time viewer — scrub the timeline, inspect per-observation payloads.
|
||||
- [ ] **Benchmark harness in CI** — keep the 95.2% R@5 number honest across releases by re-running LongMemEval-S on every minor tag.
|
||||
|
||||
## Q3 2026 — Breadth (July – September)
|
||||
|
||||
### Planned
|
||||
- [ ] **Additional maintainer onboarding** — at least one Maintainer from a different organization added via the process in `GOVERNANCE.md`. This is a prerequisite for advancing past the foundation's Growth Stage.
|
||||
- [ ] **Slack / Discord connector** — third source in the connector family.
|
||||
- [ ] **OpenSSF Scorecard** — enroll, reach a Silver-equivalent score. Badged in the README.
|
||||
- [ ] **Hermes integration hardening** — reach parity with the OpenClaw plugin surface (session lifecycle + tool-use hooks).
|
||||
- [ ] **Knowledge graph query language** — small DSL on top of `/agentmemory/graph` for multi-hop questions.
|
||||
- [ ] **First conference talk** — submit to KubeCon / LlamaCon / similar.
|
||||
|
||||
### Candidate
|
||||
- Cross-agent shared memory namespace. Currently each agent installs its own instance. This would let a Claude Code session and a Cursor session recall each other's observations via a shared mesh node.
|
||||
|
||||
## Q4 2026 — Trust (October – December)
|
||||
|
||||
### Planned
|
||||
- [ ] **SSO gateway** — accept OIDC in front of the REST surface for team deployments.
|
||||
- [ ] **Audit log export** — streamable tail to S3 / Loki / stdout for compliance pipelines.
|
||||
- [ ] **RBAC on memory scope** — `project:read`, `project:write`, `governance:delete` role set.
|
||||
- [ ] **Long-running deployment guide** — first-class Docker, systemd unit, and launchd plist.
|
||||
- [ ] **Performance SLO** — publish p50/p95 recall latency targets, enforce via the benchmark harness.
|
||||
- [ ] **Security audit** — external review of the REST surface + mesh-sync path. Fund through LF if foundation acceptance lands before end of quarter.
|
||||
|
||||
### Candidate
|
||||
- Agent-to-agent memory handoff protocol — standardize what one agent can inherit from another's memory, complementing MCP.
|
||||
|
||||
## Q1 2027 — v1.0 (January – March)
|
||||
|
||||
### Planned
|
||||
- [ ] **REST + MCP surface freeze.** Any break requires a major-version tag per `GOVERNANCE.md`.
|
||||
- [ ] **LTS branch `v1.x`** — 12-month security-fix commitment.
|
||||
- [ ] **v1.0 release** — full documentation pass, all roadmap items from prior quarters either shipped or formally deferred.
|
||||
- [ ] **Foundation membership** — Growth → Impact stage application if adoption + maintainer diversity metrics justify.
|
||||
|
||||
### Candidate
|
||||
- Hosted reference instance for the community to benchmark against.
|
||||
- Reference implementation in a second language (Rust or Go) for the MCP server — would expand the set of runtimes that can host agentmemory.
|
||||
|
||||
## Out of scope
|
||||
|
||||
For transparency, these are deliberately *not* on the roadmap:
|
||||
|
||||
- A cloud-hosted agentmemory SaaS.
|
||||
- Billing, subscription tiers, commercial licensing beyond Apache-2.0.
|
||||
- Agent frameworks themselves — agentmemory is a dependency, not a replacement for the agent runtime.
|
||||
|
||||
## Feedback
|
||||
|
||||
Anything on this list you disagree with, or think should move up / down — open an issue tagged `roadmap`. Quarterly themes are revisited with every quarterly retrospective.
|
||||
@@ -0,0 +1,85 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
**Do not open a public GitHub issue for a suspected vulnerability.**
|
||||
|
||||
Use one of:
|
||||
|
||||
- **GitHub Security Advisories (preferred)** — private report form at <https://github.com/rohitg00/agentmemory/security/advisories/new>. GitHub routes the report to the Maintainers, assigns a GHSA identifier, and keeps you in a private thread until the fix ships. All sensitive details (stack traces, credentials, exploit payloads) stay end-to-end within GitHub's security infrastructure — use this channel whenever possible.
|
||||
- **Encrypted email (fallback)** — if GitHub is unavailable or the issue cannot be described in the GHSA form, send an encrypted message to `ghumare64@gmail.com` with subject `agentmemory security`. Encrypt with the Maintainer public keys published at <https://github.com/rohitg00.gpg> (PGP) and <https://github.com/rohitg00.keys> (SSH for verification); attach your own public key so we can reply encrypted. Plaintext email is accepted only as a last resort — prefer GHSA.
|
||||
|
||||
Include, at minimum:
|
||||
|
||||
- agentmemory version (`npm view @agentmemory/agentmemory version` against your install).
|
||||
- The affected surface — REST endpoint, MCP tool, hook, CLI flag, or filesystem layout.
|
||||
- A minimal reproduction — prefer one curl invocation or one MCP tool call plus the environment state required.
|
||||
- Impact, in your own words.
|
||||
|
||||
## What we do with it
|
||||
|
||||
1. **Acknowledge** within 72 hours (target: 24).
|
||||
2. **Triage** — confirm reproduction, assign a severity using CVSS 3.1, and give you a rough timeline.
|
||||
3. **Fix** in a private branch. Draft a GitHub Security Advisory with the patched version, CWE, CVSS vector, affected versions, and attribution to you (unless you prefer anonymity).
|
||||
4. **Coordinate disclosure** — we agree a disclosure date with you. Default window is 30 days from acknowledgment for straightforward vulnerabilities, up to 90 days for ones that need a deep refactor.
|
||||
5. **Publish** — release the patched version on npm, publish the advisory, update `CHANGELOG.md` under a `### Security` section for the release, notify downstream scanners.
|
||||
|
||||
## Supported versions
|
||||
|
||||
| Version | Security fixes? |
|
||||
|-|-|
|
||||
| Latest minor (currently `0.9.x`) | Yes |
|
||||
| Previous minor (currently `0.8.x`) | Critical / High severity only, for 90 days after a new minor is released |
|
||||
| Older | No |
|
||||
|
||||
At v1.0 this policy switches to a stated LTS window per the roadmap.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- The `@agentmemory/agentmemory` server (REST + MCP surface, hook handlers, state store).
|
||||
- The `@agentmemory/mcp` standalone MCP server.
|
||||
- The `@agentmemory/fs-watcher` connector.
|
||||
- First-party integrations under `integrations/` (`hermes/`, `openclaw/`, `filesystem-watcher/`).
|
||||
- The Claude Code plugin under `plugin/`.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- Third-party MCP clients consuming agentmemory — report to those projects.
|
||||
- `iii-sdk` upstream — report to the iii project.
|
||||
- The marketing site under `website/` unless the issue affects user security (XSS against visitors, credential leak in build output).
|
||||
|
||||
## Supply-chain stance
|
||||
|
||||
agentmemory ships pre-built artifacts in the npm tarball — `dist/` is bundled at publish time, not built from `node_modules` at install time. The package's runtime dependency tree is intentionally small (6 production deps: `@anthropic-ai/sdk`, `@anthropic-ai/claude-agent-sdk`, `@clack/prompts`, `dotenv`, `iii-sdk`, `zod`) plus an optional set guarded behind `optionalDependencies` for embeddings.
|
||||
|
||||
**No lockfile is committed** (#540). The reasoning:
|
||||
|
||||
- The npm tarball ships pre-built `dist/` — fresh installs don't compile from source, so no lockfile is consulted at the user's install step.
|
||||
- The lockfile only affects contributor-local builds. Pinning it would shift the supply-chain attack surface from "what npm resolves today" to "what was resolved when the lockfile was last regenerated," which is a different tradeoff, not strictly better.
|
||||
- We use SemVer ranges (`^x.y.z`) on the published deps so security patches reach users without a re-release.
|
||||
|
||||
If you ship agentmemory inside a hardened pipeline that requires reproducible installs, the recommended path is:
|
||||
|
||||
1. `npm install --legacy-peer-deps` against the published tarball in a controlled environment.
|
||||
2. `npm shrinkwrap` to produce a versioned `npm-shrinkwrap.json` that travels with your deployment.
|
||||
3. Audit `node_modules/` once at that point and republish internally.
|
||||
|
||||
CI runs `npm install --package-lock-only --legacy-peer-deps --no-audit --no-fund` then `npm ci` against that generated lockfile, so every test job builds against a fully resolved tree. The lockfile is regenerated on each CI run rather than checked in, which keeps the published tarball aligned with whatever SemVer-compatible patch level was current at release time.
|
||||
|
||||
Supply-chain monitoring we already do:
|
||||
|
||||
- Dependabot opens PRs for every minor/patch bump on the production dep list (visible in the open PRs).
|
||||
- Every PR runs the full test suite on ubuntu-latest + macos-latest, Node 20 + 22, before any merge.
|
||||
- `optionalDependencies` (`@xenova/transformers`, `onnxruntime-node`, etc.) are guarded by `try { await import("...") } catch` so a missing or compromised optional dep cannot break the core runtime path.
|
||||
|
||||
If you find a malicious package in our dep tree, file via the GHSA flow at the top of this document — that's the fastest path to a fixed release on npm.
|
||||
|
||||
## Past advisories
|
||||
|
||||
See the [`.github/security-advisories/`](./.github/security-advisories) directory for advisory drafts. Published advisories (with assigned GHSA IDs) live at <https://github.com/rohitg00/agentmemory/security/advisories>.
|
||||
|
||||
## Safe harbor
|
||||
|
||||
Good-faith research, reported privately, does not get legal heat from the project. Research targeting third-party deployments of agentmemory is not covered — that's between you and the deployer.
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
|
||||
<path fill="#ffffff" fill-rule="evenodd" d="
|
||||
M165.29 165.29
|
||||
H517.36
|
||||
V400
|
||||
H400
|
||||
V517.36
|
||||
H282.65
|
||||
V634.72
|
||||
H165.29
|
||||
Z
|
||||
M282.65 282.65
|
||||
V400
|
||||
H400
|
||||
V282.65
|
||||
Z
|
||||
"/>
|
||||
<path fill="#ffffff" d="M517.36 400 H634.72 V634.72 H517.36 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 387 B |
|
After Width: | Height: | Size: 371 KiB |
|
After Width: | Height: | Size: 7.8 MiB |
@@ -0,0 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<rect width="64" height="64" rx="14" fill="#1A1A1A"/>
|
||||
|
||||
<!-- 4 memory tiers -->
|
||||
<rect x="14" y="40" width="36" height="5" rx="2.5" fill="#333" opacity="0.5"/>
|
||||
<rect x="14" y="33" width="36" height="5" rx="2.5" fill="#444" opacity="0.6"/>
|
||||
<rect x="14" y="26" width="36" height="5" rx="2.5" fill="#555" opacity="0.7"/>
|
||||
<rect x="14" y="19" width="36" height="5" rx="2.5" fill="url(#g)"/>
|
||||
|
||||
<!-- Active nodes on hot layer -->
|
||||
<circle cx="22" cy="21.5" r="1.8" fill="#fff"/>
|
||||
<circle cx="32" cy="21.5" r="1.8" fill="#fff"/>
|
||||
<circle cx="42" cy="21.5" r="1.8" fill="#fff"/>
|
||||
|
||||
<!-- Retrieval lines converging up -->
|
||||
<line x1="22" y1="19" x2="32" y2="12" stroke="#FF6B35" stroke-width="1" opacity="0.7"/>
|
||||
<line x1="32" y1="19" x2="32" y2="12" stroke="#FF6B35" stroke-width="1" opacity="0.5"/>
|
||||
<line x1="42" y1="19" x2="32" y2="12" stroke="#FF6B35" stroke-width="1" opacity="0.7"/>
|
||||
|
||||
<!-- Retrieval point -->
|
||||
<circle cx="32" cy="11" r="3" fill="url(#g)"/>
|
||||
<circle cx="32" cy="11" r="5" fill="none" stroke="#FF6B35" stroke-width="0.8" opacity="0.3"/>
|
||||
|
||||
<!-- Fading dots on lower tiers -->
|
||||
<circle cx="25" cy="28.5" r="1" fill="#888" opacity="0.4"/>
|
||||
<circle cx="39" cy="28.5" r="1" fill="#888" opacity="0.4"/>
|
||||
<circle cx="32" cy="35.5" r="0.8" fill="#666" opacity="0.3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 469 KiB |
|
After Width: | Height: | Size: 173 KiB |
@@ -0,0 +1,59 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="glow" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#2A2A2A"/>
|
||||
<stop offset="100%" stop-color="#1A1A1A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background circle -->
|
||||
<circle cx="60" cy="60" r="56" fill="url(#fade)" stroke="#333" stroke-width="1.5"/>
|
||||
|
||||
<!-- Memory layers (stacked rounded rects suggesting tiers) -->
|
||||
<rect x="30" y="68" width="60" height="8" rx="4" fill="#333" opacity="0.6"/>
|
||||
<rect x="30" y="56" width="60" height="8" rx="4" fill="#444" opacity="0.7"/>
|
||||
<rect x="30" y="44" width="60" height="8" rx="4" fill="#555" opacity="0.8"/>
|
||||
|
||||
<!-- Active/hot memory layer -->
|
||||
<rect x="30" y="32" width="60" height="8" rx="4" fill="url(#glow)"/>
|
||||
|
||||
<!-- Neural connection dots -->
|
||||
<circle cx="38" cy="36" r="2.5" fill="#fff" opacity="0.9"/>
|
||||
<circle cx="52" cy="36" r="2.5" fill="#fff" opacity="0.9"/>
|
||||
<circle cx="68" cy="36" r="2.5" fill="#fff" opacity="0.9"/>
|
||||
<circle cx="82" cy="36" r="2.5" fill="#fff" opacity="0.9"/>
|
||||
|
||||
<!-- Connection lines from hot layer upward (recall/retrieval) -->
|
||||
<line x1="38" y1="33" x2="48" y2="22" stroke="#FF6B35" stroke-width="1.2" opacity="0.7"/>
|
||||
<line x1="52" y1="33" x2="55" y2="20" stroke="#FF6B35" stroke-width="1.2" opacity="0.5"/>
|
||||
<line x1="68" y1="33" x2="65" y2="20" stroke="#FF6B35" stroke-width="1.2" opacity="0.5"/>
|
||||
<line x1="82" y1="33" x2="72" y2="22" stroke="#FF6B35" stroke-width="1.2" opacity="0.7"/>
|
||||
|
||||
<!-- Retrieval spark/node at top -->
|
||||
<circle cx="60" cy="18" r="4" fill="url(#glow)"/>
|
||||
<circle cx="60" cy="18" r="6" fill="none" stroke="#FF6B35" stroke-width="1" opacity="0.4"/>
|
||||
<circle cx="60" cy="18" r="9" fill="none" stroke="#FF6B35" stroke-width="0.5" opacity="0.2"/>
|
||||
|
||||
<!-- Connecting arcs to spark -->
|
||||
<line x1="48" y1="22" x2="60" y2="18" stroke="#FF6B35" stroke-width="1" opacity="0.6"/>
|
||||
<line x1="72" y1="22" x2="60" y2="18" stroke="#FF6B35" stroke-width="1" opacity="0.6"/>
|
||||
<line x1="55" y1="20" x2="60" y2="18" stroke="#FF6B35" stroke-width="0.8" opacity="0.4"/>
|
||||
<line x1="65" y1="20" x2="60" y2="18" stroke="#FF6B35" stroke-width="0.8" opacity="0.4"/>
|
||||
|
||||
<!-- Decay dots on lower layers (fading memories) -->
|
||||
<circle cx="42" cy="48" r="1.5" fill="#888" opacity="0.5"/>
|
||||
<circle cx="58" cy="48" r="1.5" fill="#888" opacity="0.5"/>
|
||||
<circle cx="74" cy="48" r="1.5" fill="#888" opacity="0.4"/>
|
||||
<circle cx="45" cy="60" r="1.2" fill="#666" opacity="0.3"/>
|
||||
<circle cx="65" cy="60" r="1.2" fill="#666" opacity="0.3"/>
|
||||
<circle cx="50" cy="72" r="1" fill="#555" opacity="0.2"/>
|
||||
<circle cx="70" cy="72" r="1" fill="#555" opacity="0.2"/>
|
||||
|
||||
<!-- Bottom text area indicator -->
|
||||
<text x="60" y="92" text-anchor="middle" font-family="Inter, system-ui, sans-serif" font-size="7.5" font-weight="800" fill="#FF6B35" letter-spacing="0.15em">AGENT</text>
|
||||
<text x="60" y="101" text-anchor="middle" font-family="Inter, system-ui, sans-serif" font-size="7.5" font-weight="400" fill="#999" letter-spacing="0.15em">MEMORY</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 28" fill="none" role="img" aria-label="divider">
|
||||
<defs>
|
||||
<linearGradient id="divGradient" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FF6B35" stop-opacity="0"/>
|
||||
<stop offset="50%" stop-color="#FF6B35" stop-opacity="0.8"/>
|
||||
<stop offset="100%" stop-color="#FF6B35" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="divAccent" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- Left line -->
|
||||
<rect x="0" y="13" width="45" height="2" rx="1" fill="url(#divGradient)"/>
|
||||
<!-- Center diamond -->
|
||||
<rect x="54" y="8" width="12" height="12" rx="3" fill="url(#divAccent)" transform="rotate(45 60 14)"/>
|
||||
<circle cx="60" cy="14" r="2" fill="#0F0F0F"/>
|
||||
<!-- Right line -->
|
||||
<rect x="75" y="13" width="45" height="2" rx="1" fill="url(#divGradient)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 977 B |
@@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 28" fill="none" role="img" aria-label="divider">
|
||||
<defs>
|
||||
<linearGradient id="divGradient" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FF6B35" stop-opacity="0"/>
|
||||
<stop offset="50%" stop-color="#FF6B35" stop-opacity="0.8"/>
|
||||
<stop offset="100%" stop-color="#FF6B35" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="divAccent" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="13" width="45" height="2" rx="1" fill="url(#divGradient)"/>
|
||||
<rect x="54" y="8" width="12" height="12" rx="3" fill="url(#divAccent)" transform="rotate(45 60 14)"/>
|
||||
<circle cx="60" cy="14" r="2" fill="#FFFFFF"/>
|
||||
<rect x="75" y="13" width="45" height="2" rx="1" fill="url(#divGradient)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 908 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 28" fill="none" role="img" aria-label="NEW: v0.8.2">
|
||||
<rect x="0" y="0" width="140" height="28" rx="6" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="12" y="18" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="11" font-weight="600" letter-spacing="1.2">NEW</text>
|
||||
<text x="128" y="18" fill="#FF6B35" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="11" font-weight="800" letter-spacing="0.5" text-anchor="end">v0.8.2</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 614 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 24" fill="none" role="img" aria-label="BETA">
|
||||
<rect x="0" y="0" width="100" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">BETA</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 449 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130 24" fill="none" role="img" aria-label="AUTO HOOK">
|
||||
<rect x="0" y="0" width="130" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">AUTO HOOK</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 459 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="MCP">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">MCP</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 447 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 24" fill="none" role="img" aria-label="NEW">
|
||||
<rect x="0" y="0" width="90" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">NEW</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="PLUGIN">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">PLUGIN</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="SECURE">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">SECURE</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="SKILL">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">SKILL</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="STABLE">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">STABLE</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="WORKS WITH EVERY AGENT">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">WORKS WITH EVERY AGENT</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">15 integrations · one memory server</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" fill="none" role="img" aria-label="API">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="200" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">API</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">109 REST endpoints</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="ARCHITECTURE">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">ARCHITECTURE</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Built on iii-engine's 3 primitives</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="BENCHMARKS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">BENCHMARKS</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Measured on LongMemEval-S (ICLR 2025)</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="VS COMPETITORS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">VS COMPETITORS</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Mem0 · Letta · Khoj · Hippo · claude-mem</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="CONFIGURATION">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">CONFIGURATION</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">LLM providers, embeddings, and more</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="DEVELOPMENT">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">DEVELOPMENT</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Hot reload, 654 tests, ~1.7s run</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="HOW IT WORKS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">HOW IT WORKS</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Hook · compress · embed · retrieve</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" fill="none" role="img" aria-label="LICENSE">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="200" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">LICENSE</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Apache-2.0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="MCP SERVER">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">MCP SERVER</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">43 tools · 6 resources · 3 prompts</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="QUICK START">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">QUICK START</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">30 seconds. No API key needed.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="SEARCH">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">SEARCH</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">BM25 + vector + knowledge graph</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="REAL-TIME VIEWER">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">REAL-TIME VIEWER</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Live observation stream on :3113</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="WHY AGENTMEMORY">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#FFFFFF"/>
|
||||
<stop offset="100%" stop-color="#F8F9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#0F172A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">WHY AGENTMEMORY</text>
|
||||
<text x="22" y="34" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Goldfish memory costs you $10/day</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="EXTERNAL DBS: 0">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#7C3AED" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">0</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">EXTERNAL DBS</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 646 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="AUTO HOOKS: 12">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#EA580C" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">12</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">AUTO HOOKS</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 644 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="RETRIEVAL R@5: 95.2%">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#16A34A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">95.2%</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">RETRIEVAL R@5</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 656 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="TESTS PASSING: 1390+">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#16A34A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">1390+</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">TESTS PASSING</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 657 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="FEWER TOKENS: 92%">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#16A34A" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">92%</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">FEWER TOKENS</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 650 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 48" fill="none" role="img" aria-label="MCP TOOLS: 53">
|
||||
<rect x="0" y="0" width="140" height="48" rx="10" fill="#FFFFFF" stroke="#E5E7EB" stroke-width="1"/>
|
||||
<text x="70" y="24" fill="#EA580C" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="18" font-weight="900" text-anchor="middle" letter-spacing="-0.3">53</text>
|
||||
<text x="70" y="38" fill="#64748B" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="9" font-weight="600" text-anchor="middle" letter-spacing="1.5">MCP TOOLS</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 643 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 28" fill="none" role="img" aria-label="NEW: v0.8.2">
|
||||
<rect x="0" y="0" width="140" height="28" rx="6" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<text x="12" y="18" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="11" font-weight="600" letter-spacing="1.2">NEW</text>
|
||||
<text x="128" y="18" fill="#FF6B35" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="11" font-weight="800" letter-spacing="0.5" text-anchor="end">v0.8.2</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 614 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 24" fill="none" role="img" aria-label="BETA">
|
||||
<rect x="0" y="0" width="100" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">BETA</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 449 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130 24" fill="none" role="img" aria-label="AUTO HOOK">
|
||||
<rect x="0" y="0" width="130" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">AUTO HOOK</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 459 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="MCP">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">MCP</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 447 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 24" fill="none" role="img" aria-label="NEW">
|
||||
<rect x="0" y="0" width="90" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">NEW</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="PLUGIN">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">PLUGIN</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="SECURE">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">SECURE</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="SKILL">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">SKILL</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 24" fill="none" role="img" aria-label="STABLE">
|
||||
<rect x="0" y="0" width="110" height="24" rx="12" fill="#1A1A1A" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<circle cx="12" cy="12" r="3" fill="#FF6B35"/>
|
||||
<text x="22" y="16" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="700" letter-spacing="1.2">STABLE</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="WORKS WITH EVERY AGENT">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">WORKS WITH EVERY AGENT</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">15 integrations · one memory server</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" fill="none" role="img" aria-label="API">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="200" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">API</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">109 REST endpoints</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="ARCHITECTURE">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">ARCHITECTURE</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Built on iii-engine's 3 primitives</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="BENCHMARKS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">BENCHMARKS</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Measured on LongMemEval-S (ICLR 2025)</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 44" fill="none" role="img" aria-label="VS COMPETITORS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="320" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">VS COMPETITORS</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Mem0 · Letta · Khoj · Hippo · claude-mem</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="CONFIGURATION">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">CONFIGURATION</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">LLM providers, embeddings, and more</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="DEVELOPMENT">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">DEVELOPMENT</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Hot reload, 654 tests, ~1.7s run</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="HOW IT WORKS">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">HOW IT WORKS</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Hook · compress · embed · retrieve</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" fill="none" role="img" aria-label="LICENSE">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="200" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">LICENSE</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Apache-2.0</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="MCP SERVER">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">MCP SERVER</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">43 tools · 6 resources · 3 prompts</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="QUICK START">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">QUICK START</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">30 seconds. No API key needed.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 44" fill="none" role="img" aria-label="SEARCH">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="260" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">SEARCH</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">BM25 + vector + knowledge graph</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 44" fill="none" role="img" aria-label="REAL-TIME VIEWER">
|
||||
<defs>
|
||||
<linearGradient id="accent" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#FF6B35"/>
|
||||
<stop offset="100%" stop-color="#FF8F5E"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1A1A1A"/>
|
||||
<stop offset="100%" stop-color="#0F0F0F"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="280" height="44" rx="8" fill="url(#bg)" stroke="#2A2A2A" stroke-width="1"/>
|
||||
<rect x="0" y="0" width="6" height="44" rx="3" fill="url(#accent)"/>
|
||||
<text x="22" y="20" fill="#FFFFFF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="13" font-weight="800" letter-spacing="2.2" text-rendering="geometricPrecision">REAL-TIME VIEWER</text>
|
||||
<text x="22" y="34" fill="#9CA3AF" font-family='ui-sans-serif, -apple-system, "Segoe UI", Inter, system-ui, sans-serif' font-size="10" font-weight="500" letter-spacing="0.2" text-rendering="geometricPrecision">Live observation stream on :3113</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |