Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
"name": "pstack",
"source": "pstack",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence."
},
{
"name": "evolver",
"source": "evolver",
"description": "Persistent, auditable evolution memory for the agent: recalls what worked on past tasks at session start, detects improvement signals while you edit, and records outcomes when a task ends. Powered by the Genome Evolution Protocol (GEP)."
}
]
}
33 changes: 33 additions & 0 deletions evolver/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "evolver",
"displayName": "Evolver — Self-Evolving Agent Memory",
"description": "Gives the agent a persistent, auditable evolution memory. Recalls what worked on past tasks at session start, detects improvement signals while you edit, and records outcomes when a task ends — powered by the Genome Evolution Protocol (GEP). The hooks degrade gracefully without a local install; add the `@evomap/evolver` npm package to unlock the full review-and-solidify pipeline and EvoMap Hub sync.",
"version": "0.1.0",
"author": {
"name": "EvoMap",
"email": "team@evomap.ai"
},
"publisher": "EvoMap",
"homepage": "https://evomap.ai",
"repository": "https://github.com/EvoMap/evolver-cursor-plugin",
"license": "MIT",
"logo": "assets/logo.png",
"keywords": [
"evolution",
"self-improvement",
"agent-memory",
"gep",
"meta-learning",
"evomap"
],
"category": "developer-tools",
"tags": [
"memory",
"automation",
"self-improvement"
],
"skills": "./skills/",
"commands": "./commands/",
"rules": "./rules/",
"hooks": "./hooks/hooks.json"
}
5 changes: 5 additions & 0 deletions evolver/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
*.log
.env
.env.*
.DS_Store
21 changes: 21 additions & 0 deletions evolver/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 EvoMap

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
122 changes: 122 additions & 0 deletions evolver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Evolver — Self-Evolving Agent Memory (Cursor Plugin)

Give the Cursor agent a **persistent, auditable evolution memory**. Instead of
re-solving the same problem every session, the agent recalls what worked
before, notices improvement signals as it edits, and records how each task
turned out — so the next session starts smarter.

Powered by the [Genome Evolution Protocol (GEP)](https://evomap.ai) and the
[`@evomap/evolver`](https://github.com/EvoMap/evolver) engine.

> **Status:** v0.1.0 — hooks + skill + rule. Works standalone (local memory).
> The MCP tool surface is provided separately by
> [`@evomap/gep-mcp-server`](https://github.com/EvoMap/gep-mcp-server) and is
> intentionally **not** bundled here (see *Architecture* below).

## What it does

Three hooks run automatically — you don't invoke them:

| Hook | Event | Effect |
|---|---|---|
| `session-start.js` | `sessionStart` | Injects a summary of recent **successful** outcomes (score ≥ 0.5, < 7 days, max 3) as context. |
| `signal-detect.js` | `afterFileEdit` | Detects improvement signals (`log_error`, `perf_bottleneck`, `capability_gap`, …) in edits. |
| `session-end.js` | `stop` | Classifies the task's git diff and appends the outcome to the evolution memory graph. |

It also ships:

- A **`capability-evolver` skill** describing the recall → work → record loop.
- An **`/evolve` command** for a deliberate evolution checkpoint.
- A **rule** that reminds the agent to use evolution memory on substantive work.

## Install

### From the Cursor Marketplace

Search for **Evolver** in the Cursor plugin marketplace and install.

### Local development

```bash
git clone https://github.com/EvoMap/evolver-cursor-plugin
ln -s "$(pwd)/evolver-cursor-plugin" ~/.cursor/plugins/local/evolver
```

Reload Cursor. The hooks activate on the next session.

## Requirements

- **Node.js** (the hooks are Node scripts; Cursor invokes them via `node`).
- Nothing else for local memory.

## Modes

### Local mode (default, zero config)

Out of the box the hooks write outcomes to
`~/.evolver/memory/evolution/memory_graph.jsonl` (or, inside an evolver-managed
project, that project's `memory/evolution/`). Recall and record work
immediately. **No account, no key, no network.**

### Full engine

```bash
npm install -g @evomap/evolver
```

The bundled hooks always do lightweight **local** recall/record — local git
diff + JSONL append, plus optional Hub sync. Installing `@evomap/evolver` does
**not** change what the hooks do and they do not auto-detect or invoke it.
What it adds is the engine's **CLI** — e.g. `evolver run` (the full automated
review-and-solidify pipeline that analyzes logs and proposes/applies code
improvements) and `evolver review` — which you run separately. The memory the
hooks record feeds that pipeline, so the two compose without the hooks ever
shelling out to the engine.

### EvoMap Hub (community strategies)

To sync outcomes and search strategies published by other agents, register an
EvoMap node and set the Hub credentials in your environment:

```bash
export EVOMAP_HUB_URL="https://evomap.ai"
export EVOMAP_API_KEY="…" # from your EvoMap node
export EVOMAP_NODE_ID="…"
```

The `stop` hook will then record outcomes to the Hub (with a local fallback if
the Hub is unreachable). See the [evolver docs](https://evomap.ai) for node
registration.

## Architecture (why no bundled MCP server)

EvoMap deliberately splits two products:

- **`@evomap/evolver`** — the GPL-licensed, source-available evolution engine
(daemon + CLI). This plugin does **not** bundle it; the plugin's own hooks are
an independent MIT clean-room implementation that records memory in the same
format the engine reads, so the two interoperate when you install it.
- **`@evomap/gep-mcp-server`** — an Apache-licensed, standalone **protocol
layer** that exposes GEP capabilities as MCP tools to any MCP client.

This plugin ships its own lightweight session-lifecycle hooks (the glue Cursor
needs), which work standalone and degrade gracefully. If you also want the
`gep_*` MCP tools inside Cursor, add `@evomap/gep-mcp-server` to your Cursor MCP
config directly — it is not re-bundled here to avoid duplicating that
separately-maintained product.

## Environment variables

| Variable | Default | Purpose |
|---|---|---|
| `MEMORY_GRAPH_PATH` | (auto) | Override the memory graph file location. |
| `EVOMAP_HUB_URL` / `EVOMAP_API_KEY` / `EVOMAP_NODE_ID` | (unset) | Enable Hub recording. |
| `EVOLVER_HOOK_VERBOSE` | `0` | Set `1` to surface the session-end receipt inline (suppressed on Cursor by default). |

## License

MIT © EvoMap. The bundled hook scripts are an original, clean-room
implementation written against the hook behavior spec — they are not derived
from the GPL-licensed `@evomap/evolver` source. Installing `@evomap/evolver`
(itself GPL) to unlock the full pipeline is an independent, optional step. See
`LICENSE`.
Binary file added evolver/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions evolver/commands/evolve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
description: Run an evolution cycle — recall relevant past outcomes, reflect on the current task, and record what was learned.
---

# /evolve

Trigger a deliberate evolution step for the current task.

1. **Recall.** Look at the evolution memory the session-start hook injected (or
read the tail of the memory graph at
`~/.evolver/memory/evolution/memory_graph.jsonl`, or the project's
`memory/evolution/memory_graph.jsonl` if present). Summarize any recent
outcome — success or failure — that is relevant to what we're working on.

2. **Reflect.** Given the current diff / task state, state in one or two lines:
what worked, what didn't, and what the durable lesson is.

3. **Record.** The `stop` hook records outcomes automatically at task end. If
the user wants to record *now*, and the full engine is installed
(`@evomap/evolver` on `PATH`), run:

```bash
evolver run
```

to execute a full evolution cycle. If it is not installed, tell the user the
outcome will still be captured automatically by the stop hook, and that
`npm install -g @evomap/evolver` unlocks the full review-and-solidify cycle.

Keep this lightweight — `/evolve` is for an explicit checkpoint, not a ceremony
on every turn.
65 changes: 65 additions & 0 deletions evolver/hooks/_filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2026 EvoMap
//
// Relevance filter for evolution memory entries. Decides which recorded
// outcomes are worth surfacing back to the agent at session start.

'use strict';

const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
const MIN_SCORE = 0.5;
const MAX_RESULTS = 3;

/**
* Parse an entry timestamp into epoch milliseconds, or NaN if absent/invalid.
*/
function timestampMs(entry) {
if (!entry || typeof entry.timestamp !== 'string') {
return NaN;
}
return Date.parse(entry.timestamp);
}

/**
* Keep only recent, successful, high-scoring outcomes — at most the latest 3.
*
* An entry survives when ALL of the following hold:
* - outcome.status === 'success'
* - outcome.score >= 0.5
* - its timestamp is within the last 7 days
*
* @param {Array<object>} entries
* @returns {Array<object>}
*/
function filterRelevant(entries) {
if (!Array.isArray(entries)) {
return [];
}

const now = Date.now();
const cutoff = now - SEVEN_DAYS_MS;

const relevant = entries.filter((entry) => {
const outcome = entry && entry.outcome;
if (!outcome || outcome.status !== 'success') {
return false;
}
if (typeof outcome.score !== 'number' || outcome.score < MIN_SCORE) {
return false;
}
const ts = timestampMs(entry);
if (Number.isNaN(ts)) {
return false;
}
return ts >= cutoff && ts <= now;
});

// The input arrives chronologically; the most useful items are the latest,
// so keep the tail.
if (relevant.length > MAX_RESULTS) {
return relevant.slice(relevant.length - MAX_RESULTS);
}
return relevant;
}

module.exports = { filterRelevant };
Loading