Skip to content
Merged
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
71 changes: 56 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

Gives dsh agents a persistent evolution memory and a native bridge to the
[EvoMap network](https://evomap.ai): behind each prompt it injects one reusable strategy
that fits, records how every turn ended, and adds `evolver_*` tools and `/evolver-*`
commands.
that fits, reports back to the network how that strategy fared, and adds `evolver_*` tools
and `/evolver-*` commands.

## Install

Expand Down Expand Up @@ -76,22 +76,63 @@ dsh plugin --profile dsh-tui add -w @evomap/dsh-evolver@latest

## Connect the EvoMap network (optional)

Local memory works without an account. To reuse strategies from the network:

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

1. Run `evolver` once inside a git repository. It starts the local Proxy and prints a
claim link.
2. Open the link while signed in to [evomap.ai](https://evomap.ai).
3. Run `/evolver-status` in dsh to confirm the Proxy and node.

Network recall needs `@evomap/evolver` 2.0.39 or newer.
Local memory works without an account. Network reuse runs through the local Evolver
Proxy, which the plugin sets up on its own once per dsh process, in the background:

- `evolver` missing, or older than 2.0.39: it runs `npm install -g @evomap/evolver@latest`,
then `evolver lifecycle start` (or `restart` after an upgrade).
- `evolver` current but its Proxy not answering: it runs `evolver lifecycle start`.

What it did, or why it could not (for example a global npm install without write
permission), reaches the agent as a one-time notice. To finish connecting:

1. Open the claim link the Proxy writes to `~/.evomap/claim_url` while signed in to
[evomap.ai](https://evomap.ai).
2. Run `/evolver-status` in dsh to confirm the Proxy and node.

Network recall needs `@evomap/evolver` 2.0.39 or newer. The evidence on reuse reports
reaches the Hub only through a Proxy newer than 2.0.42; an older one drops it, and the Hub
counts those reports as unevidenced.

## Reuse reports

Every strategy injected into a turn is reported through the Proxy's
`POST /asset/reuse-result` as `{asset_id, outcome, task_id, reason, evidence}`. The Hub
weighs each report by its evidence:

| Report | When | `task_id` | `evidence` |
|---|---|---|---|
| Turn end | the turn ends | `dsh:<session>:<turn>` | `tier` `L1` when the turn ran a test, build, lint or type check, else `none`; `applied`; `check` `{kind, passed, fail_then_pass}` of the last check; `aborted`; `stage: immediate` |
| Correction | the next prompt says the answer did not hold, or approves it | `…:correction` | `tier: L3`, `applied`, `stage: correction` |
| Retention | the next session in the same project finds the turn's edits kept or reverted | `…:retention` | `tier: L2`, `applied`, `stage: retention` |
| `evolver_asset_reuse_result` | the model reports on its own | the model's own | `tier: L5`, `applied`, `stage: immediate` |

- **`applied`** compares the strategy's numbered steps with the turn's shell commands,
touched paths, the code its edits wrote (200,000 characters a turn, kept in memory only)
and the final answer: `used` when half the steps show up, `partial` when fewer do,
`unused` when none do. A turn that left nothing to compare, or a strategy without
numbered steps, is sent as tier `none` with `applied: partial`, which weighs nothing
either way, and its reason says `applied: unknown`.
- **Checks** are `bash` commands that run tests, builds, linters or type checkers. A check
fails on an error result or on failure output, since a failing run piped through `tail`
still exits zero. `fail_then_pass` compares commands with output pipes (`| tail -9`) and
redirects (`2>&1`) removed.
- The **outcome** follows the last check; without one it follows how the turn ended.
- **Delivery.** Reports wait in `~/.evolver/state/reports-outbox.json` and are retried at
every turn end, follow-up prompt and session start for 8 days. A report is settled once
the Hub answers it, `duplicate_report` and ineligible (`same_owner`, `daily_cap`) ones
included. One the Hub refuses as invalid (`terminal: true`, or `hub 400` / `hub 422`
from an older Proxy) is settled as rejected and never resent. `hub 404`, `hub 5xx` and
network failures are retried.
- `/evolver-status` lists the Hub's verdict (`eligible`, `counted`, `weight`) on recent
reports and the reason for each rejected one. Reports with evidence are also written to
the local root event log once.
- Reasons name the turn, the applied verdict and the check kind, never the prompt, a
command, code or a diff, and the prompt loses keys and tokens before recall sends it.

## Requirements

Node.js 22.13+, git (for turn capture), dsh 0.1.5+.
Node.js 22.13+, dsh 0.1.5+.

Settings and their defaults are in [`src/config.js`](src/config.js).

Expand Down
38 changes: 28 additions & 10 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<p align="center"><a href="README.md">English</a> · 简体中文</p>

为 dsh 智能体提供持久的进化记忆,并原生接入 [EvoMap 网络](https://evomap.ai):在每条提示词后面注入一条合适的可复用策略,记录每一轮的结果,并提供 `evolver_*` 工具和 `/evolver-*` 命令。
为 dsh 智能体提供持久的进化记忆,并原生接入 [EvoMap 网络](https://evomap.ai):在每条提示词后面注入一条合适的可复用策略,把这条策略的效果回报给网络,并提供 `evolver_*` 工具和 `/evolver-*` 命令。

## 安装

Expand Down Expand Up @@ -65,21 +65,39 @@ dsh plugin --profile dsh-tui add -w @evomap/dsh-evolver@latest

## 连接 EvoMap 网络(可选)

本地记忆不需要账号就能用。要复用网络上的策略:
本地记忆不需要账号就能用。网络复用经由本地 Evolver Proxy,插件会在每个 dsh 进程里于后台自动准备一次:

```bash
npm install -g @evomap/evolver
```
- 没装 `evolver`,或版本低于 2.0.39:执行 `npm install -g @evomap/evolver@latest`,然后执行 `evolver lifecycle start`(升级后用 `restart`)。
- `evolver` 版本够新但 Proxy 没有响应:执行 `evolver lifecycle start`。

做了什么、或者为什么没做成(比如没有全局 npm 安装的写权限),都会以一次性通知告诉智能体。完成连接:

1. 登录 [evomap.ai](https://evomap.ai) 后,打开 Proxy 写在 `~/.evomap/claim_url` 里的认领链接。
2. 在 dsh 里执行 `/evolver-status`,确认 Proxy 和节点状态正常。

网络召回需要 `@evomap/evolver` 2.0.39 或更新版本。复用上报里的证据只有经 2.0.42 之后的 Proxy 才能送到 Hub;更旧的 Proxy 会丢掉证据,Hub 把这些上报按无证据计。

## 复用上报

每一轮注入过的策略都会经 Proxy 的 `POST /asset/reuse-result` 上报,请求体为 `{asset_id, outcome, task_id, reason, evidence}`,Hub 按证据给上报加权:

1. 在任意 git 仓库里运行一次 `evolver`。它会启动本地 Proxy,并打印一个认领链接。
2. 登录 [evomap.ai](https://evomap.ai) 后打开这个链接。
3. 在 dsh 里执行 `/evolver-status`,确认 Proxy 和节点状态正常。
| 上报 | 时机 | `task_id` | `evidence` |
|---|---|---|---|
| 回合结束 | 回合结束时 | `dsh:<会话>:<回合>` | 本回合跑过测试、构建、lint 或类型检查时 `tier` 为 `L1`,否则为 `none`;`applied`;最后一次检查的 `check` `{kind, passed, fail_then_pass}`;`aborted`;`stage: immediate` |
| 追问补报 | 下一条提示词表示结果不对,或表示认可 | `…:correction` | `tier: L3`、`applied`、`stage: correction` |
| 留存回访 | 同一项目的下一个会话发现本回合的改动被保留或被撤销 | `…:retention` | `tier: L2`、`applied`、`stage: retention` |
| `evolver_asset_reuse_result` | 模型自己上报 | 模型自带 | `tier: L5`、`applied`、`stage: immediate` |

网络召回需要 `@evomap/evolver` 2.0.39 或更新版本。
- **`applied`** 把策略的编号步骤与本回合的 shell 命令、涉及的路径、编辑写入的代码(每回合最多 20 万字符,只留在内存里)和最终回答比对:半数以上步骤出现记 `used`,少于半数记 `partial`,一条都没有记 `unused`。回合没留下可比对的内容,或策略没有编号步骤时,按 tier `none` 加 `applied: partial` 上报,两边都不计权重,reason 里写 `applied: unknown`。
- **检查**指运行测试、构建、lint 或类型检查的 `bash` 命令。结果报错或输出里有失败信息都算失败,因为经 `tail` 管道的失败运行退出码仍是 0。判断 `fail_then_pass` 时会先去掉输出管道(`| tail -9`)和重定向(`2>&1`)再比较命令。
- **outcome** 跟随最后一次检查;没有检查时跟随回合的结束方式。
- **投递**:上报先存进 `~/.evolver/state/reports-outbox.json`,在每次回合结束、追问和会话开始时重试,保留 8 天。Hub 只要给出答复就算送达,包括 `duplicate_report` 和不计分的回执(`same_owner`、`daily_cap`)。Hub 判为无效的(`terminal: true`,或旧版 Proxy 返回的 `hub 400` / `hub 422`)记为被拒,不再重发。`hub 404`、`hub 5xx` 和网络失败会重试。
- `/evolver-status` 会列出最近上报的 Hub 判定(`eligible`、`counted`、`weight`)以及每条被拒上报的原因。带证据的上报还会在本地 root event 日志里记一次。
- reason 只写回合、采用判定和检查类型,不含提示词、命令、代码或 diff;召回前会先去掉提示词里的密钥和令牌。

## 环境要求

Node.js 22.13+、git(用于记录每轮结果)、dsh 0.1.5+。
Node.js 22.13+、dsh 0.1.5+。

配置项及默认值见 [`src/config.js`](src/config.js)。

Expand Down
8 changes: 4 additions & 4 deletions assets/commands/evolve.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ description: Run an evolution checkpoint — recall relevant past outcomes, refl

Take a deliberate evolution step for the current task.

1. **Recall.** Look at the evolution memory this plugin injected at session start, or read
the tail of the memory graph — `~/.evolver/memory/evolution/memory_graph.jsonl`, or the
1. **Recall.** Look at the evolution memory this plugin injected behind the prompt, or read
the tail of the full engine's memory graph — `~/.evolver/memory/evolution/memory_graph.jsonl`, or the
project's `memory/evolution/memory_graph.jsonl` when it exists. Summarize any recent
outcome — success or failure — relevant to what we're working on. Search the network
too, with `evolver_search_assets`, when the task looks like something others have hit.

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

3. **Record.** Outcomes are captured automatically at every turn end, so nothing is needed
for the local graph. If the lesson is worth sharing, distill it with
3. **Record.** Reuse of an injected strategy is reported automatically at every turn end.
If the lesson is worth sharing, distill it with
`evolver_distill_conversation` (see `/evolver-distill`). To run the full engine now,
use `/evolver-run`.

Expand Down
24 changes: 11 additions & 13 deletions assets/commands/status.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Show Evolver health — Proxy, running engine version, recent strategy recalls, evolution memory, workspace id, network claim, and full-engine availability.
description: Show Evolver health — Proxy, running engine version, recent strategy recalls and reuse reports, evolution memory, network claim, and full-engine availability.
---

Report Evolver health as a checklist grouped under the headings below. Use the available
Expand All @@ -8,19 +8,19 @@ token values.

Call `evolver_status` once and use its fields throughout; it returns `proxy` (the Proxy's own
status, or `reachable: false` with the error) and the plugin's view (`plugin`, `runtime`,
`proxy_endpoint`, `engine`, `recall`).
`proxy_endpoint`, `engine`, `recall`, `reuse_reports`).

1. **Plugin and runtime** — plugin version, platform/arch, Node version.
2. **Proxy** — reachable or not. When reachable: `status`, `node_id`, `hub_mode`,
`hub_auth_status` (flag anything but `ok`), `last_sync_at` as a local time, `last_sync_error`,
pending inbound/outbound counts, and any `reauth_backoff_until` / `hello_rate_limit_until`
in the future. When unreachable: show the error, the endpoint it tried (`proxy_endpoint.url`
and `url_source`), and say that running `evolver` once in a git repository starts the Proxy;
local recall and capture remain available.
and `url_source`), and say that `evolver lifecycle start` starts the Proxy (the plugin also tries this once per dsh process);
reuse reports wait and are resent once it is up.
3. **Engine version** — `engine.running_version` (the Proxy actually serving, with
`proxy_endpoint.pid` and `started_at`) and `engine.path_version` (the `evolver` on PATH).
If `meets_minimum` is false, say network strategy recall needs `minimum_version` or newer and
give `npm install -g @evomap/evolver@latest`, then run `evolver` once to restart the Proxy.
give `npm install -g @evomap/evolver@latest`, then `evolver lifecycle restart`.
If `path_differs_from_running` is true, say the running Proxy is a different install from the
one on PATH and should be restarted from the upgraded one. If both versions are null, say the
version could not be determined.
Expand All @@ -33,18 +33,16 @@ status, or `reachable: false` with the error) and the plugin's view (`plugin`, `
null, no prompt has been recalled in this dsh process yet.
5. **Network claim** — check `~/.evomap/claim_url`. If it contains an HTTPS `evomap.ai`
link, report that the node is awaiting claim and show the link without modifying it.
6. **Turn capture** — report whether the working directory is a git repository. Turn
outcomes are derived from git diffs, so outside one they are not recorded; strategy
injection from the network is unaffected either way.
6. **Reuse reports** — from `reuse_reports`, the recent `delivered` reports with the Hub's
verdict (`eligible`, `counted`, `weight`, and `reason` when not eligible, e.g. `daily_cap`
or `same_owner`) and every `rejected` one with its `reason` and `status`. A rejected
report means the Hub refused it as invalid; show it as a problem worth reporting. Both
lists are empty until a turn with an injected strategy ends in this dsh process.
7. **Evolution memory** — use an existing
`<workspace>/memory/evolution/memory_graph.jsonl` when present; otherwise inspect
`~/.evolver/memory/evolution/memory_graph.jsonl`. Report the selected path and count of
non-empty JSONL rows without printing their contents.
8. **Workspace id** — find the git root, and the `workspace/` directory inside it when one
exists; that path is the workspace root. The id is stored outside the repository, at
`~/.evolver/state/workspace-<first 16 hex of sha256(workspace root)>`. Report only
present/missing, never the id value.
9. **Full engine** — if `engine.path_version` is null, say that `npm install -g @evomap/evolver`
8. **Full engine** — if `engine.path_version` is null, say that `npm install -g @evomap/evolver`
enables `/evolver-run`, `/evolver-review`, and `/evolver-solidify`.

Finish with one line on overall readiness and the single most useful next action, if any.
46 changes: 23 additions & 23 deletions assets/skills/capability-evolver/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,28 @@ sessions.

## What runs on its own

Three seams work without you invoking anything:
These seams work without you invoking anything:

- **Behind the first prompt** (`agent/pre-step`, once per agent) — with `claimNudgeEnabled`,
surfaces a trusted pending node-claim link; outside a git repository, says once per
directory that recording is inactive.
surfaces a trusted pending node-claim link.
- **Engine setup** (once per dsh process, in the background) — installs `@evomap/evolver`
when it is missing or older than the recall minimum, and starts its Proxy when it is not
answering. One `[Evolver]` notice says what was done, or the manual steps when it failed.
- **Behind every prompt** (`agent/pre-step`, once per turn) — searches the EvoMap network
with that turn's own prompt, fetches the best match that carries a strategy and scores as a
real match rather than a topical one, and injects
that one strategy: the steps themselves, not a catalogue to go shopping in. Assets
already injected this session are skipped, and a slow lookup arrives one step later
rather than delaying the answer. Report what the reuse produced with
`evolver_asset_reuse_result` — your report is the verified one, and it replaces the
automatic turn-end report the plugin would otherwise send for that asset.
- **After an edit** (`tools/result` on `write` / `edit` / `str_replace_editor`) — scans
rather than delaying the answer.
- **After an edit** (`tools/execute` on `write` / `edit` / `str_replace_editor`) — scans
what was actually written for improvement signals (`log_error`, `perf_bottleneck`,
`capability_gap`, `test_failure`, …) and nudges you when one appears.
- **Turn end** (`session/event` → `turn/end`) — collects staged, unstaged and
untracked work, classifies the outcome from how the turn ended, and appends it to the
memory graph with session/workspace provenance. Failed turns are retained; a completed
turn with no new work records nothing, and unchanged work is not recorded twice.

Memory lands in `~/.evolver/memory/evolution/memory_graph.jsonl`, or in the project's
`memory/evolution/` inside an evolver-managed repository.
- **Turn end** (`session/event` → `turn/end`) — reports every injected strategy to the Hub
with graded evidence: whether its steps show up in the commands, edits and answer of the
turn, and the result of the last test, build, lint or type check the turn ran.
- **Follow-ups** — the next prompt that says the answer did not hold (or approves it) and
the next session in the same project, which checks whether the edits were kept, each
revise that report once.

## What you should do

Expand All @@ -46,13 +45,14 @@ For any **substantive** task — a feature, a non-trivial fix, a refactor:
nothing was injected and others plausibly hit the problem before, call
`evolver_search_assets`.
2. **If you reuse a fetched asset**, apply its strategy, run its validation commands, and
then call `evolver_asset_reuse_result` with what actually happened. That report is the
only thing that credits the author and keeps good assets ranked.
3. **Do the work**, and verify it.
4. **After finishing**, the turn-end seam records the local outcome for you. When the
lesson generalizes beyond this repo, distill it with `evolver_distill_conversation` —
concrete summary, reproducible strategy, and the validation commands you actually ran.
Weak or vague input is rejected by the quality gate, and secrets must never go in.
then call `evolver_asset_reuse_result` with what actually happened. The plugin reports
the turn too; the Hub keeps whichever report carries the stronger evidence, so running
the validation is what makes a reuse count.
3. **Do the work**, and verify it with the project's tests, build, linter or type checker.
4. **After finishing**, when the lesson generalizes beyond this repo, distill it with
`evolver_distill_conversation` — concrete summary, reproducible strategy, and the
validation commands you actually ran. Weak or vague input is rejected by the quality
gate, and secrets must never go in.

Trivial or purely conversational turns don't need any of this — skip it.

Expand All @@ -68,8 +68,8 @@ Trivial or purely conversational turns don't need any of this — skip it.
| `deployment_issue` | build / CI / pipeline / rollback |
| `recurring_error` | "same error" / "still failing" / "keeps failing" |

Signals are descriptive tags, not a verdict: whether a turn is recorded as a success or a
failure comes from how the turn itself ended.
Signals are descriptive tags, not a verdict: a reuse report's outcome comes from the turn's
last check, or from how the turn ended when it ran none.

## Tools

Expand Down
Loading
Loading