---
sidebar_position: 5
title: "@zibby/ui-memory"
---

# @zibby/ui-memory

Version-controlled UI agent memory powered by [Dolt](https://www.dolthub.com/). Learns from every test run — selectors that worked, page-element fingerprints, navigation transitions, timing quirks, recorded insights. Used today by `zibby test`; designed to power any agent that drives a UI.

```bash
npm install @zibby/ui-memory
```

Current version: **1.1.0**

> Renamed from `@zibby/memory` to make the per-domain UI focus explicit. This package is the **UI test-memory** store (Dolt-backed, per-domain). For chat-style agent memory — facts, decisions, task history — see the [Chat memory skill](../skills/chat-memory.md), which defaults to a **mem0** semantic backend (with automatic fallback to Dolt) and can be pinned to Dolt explicitly.

## Why memory

Without memory, every test run starts from scratch. The agent has no idea which selectors are stable, which pages have changed, or what workarounds were discovered last week.

With `@zibby/ui-memory`:

- **Selectors** — the agent prefers selectors with high success / low fail counts
- **Page model** — known elements, ARIA roles, accessible names
- **Navigation** — known page-to-page transitions (which click produced which URL)
- **Test history** — pass/fail trends per spec, full timing
- **Insights** — categorized free-form notes the agent reads + writes (`selector_tip | timing | navigation | workaround | flaky | general`)

Critically, memory is keyed **per domain**, not per spec. A selector that one spec learned for `myapp.com/login` is available to every other spec hitting the same site.

## Setup

Most users get this automatically via `zibby init` — Dolt is bundled, the DB is initialized, and `zibby test` writes to it. The notes below are for direct package consumption.

### 1. Install Dolt (if not bundled)

```bash
# macOS
brew install dolt

# Linux
sudo bash -c 'curl -L https://github.com/dolthub/dolt/releases/latest/download/install.sh | bash'
```

### 2. Initialize the database

```bash
zibby memory init
```

Creates `.zibby/memory/.dolt/` with the schema for runs, selectors, page model, navigation, and insights.

### 3. Enable memory in your agent

Add `SKILLS.MEMORY` to any node that should have memory access:

```javascript
import { SKILLS } from '@zibby/core';

export const executeLiveNode = {
  name: 'execute_live',
  skills: [SKILLS.BROWSER, SKILLS.MEMORY],
  // ...
};
```

The built-in `execute_live` node already has memory enabled.

## How it works

### Before each run

The runner auto-pulls from the configured remote (if any) and loads the relevant slice into the agent's context — selectors for the page, recent failures, applicable insights.

### During the run

The agent has 5 MCP tools auto-exposed:

| Tool | What it does |
|---|---|
| `memory_get_test_history` | Recent runs — filter by spec-path substring; returns pass/fail/timing |
| `memory_get_selectors` | Known selectors per page with success/fail counts |
| `memory_get_page_model` | Page elements (URL, ARIA role, accessible name, best selector) |
| `memory_get_navigation` | Known transitions (from URL → to URL via what trigger) |
| `memory_save_insight` | Save observation: `selector_tip | timing | navigation | workaround | flaky | general` |

### After the run

The result handler persists the new state — selectors used (with success/failure deltas), page-model updates, new navigation transitions discovered, and any insights the agent saved.

> **The agent is required to call `memory_save_insight` at least once at the end of every run.** This is in the memory skill's prompt fragment. Without insights, memory degrades to cached selectors and run rows; with them it compounds.

### Version control

Every persist creates a Dolt commit. You can:

```bash
cd .zibby/memory
dolt log
dolt diff HEAD~1 HEAD
dolt branch experiment
dolt checkout experiment
```

## Database schema

### `test_runs`

| Column | Type | Description |
|---|---|---|
| `session_id` | VARCHAR | Unique session identifier |
| `spec_path` | VARCHAR | Path to the test spec file |
| `passed` | BOOLEAN | Whether the test passed |
| `duration_ms` | INT | Total execution time |
| `agent_type` | VARCHAR | Which agent ran the test |
| `tokens_input` / `tokens_output` / `tokens_cache_*` | INT | LLM token usage (drives `zibby memory cost`) |
| `created_at` | DATETIME | Timestamp |

### `selectors`

| Column | Type | Description |
|---|---|---|
| `page_url` | VARCHAR | URL where this selector was used |
| `selector` | VARCHAR | The CSS/XPath selector string |
| `stable_id` | VARCHAR | Zibby stable ID (if available) |
| `success_count` | INT | Times this selector worked |
| `fail_count` | INT | Times this selector failed |
| `last_used` | DATETIME | Last usage timestamp |

### `page_model`

| Column | Type | Description |
|---|---|---|
| `url` | VARCHAR | Page URL |
| `element_role` | VARCHAR | ARIA role |
| `element_name` | VARCHAR | Accessible name |
| `selector` | VARCHAR | Best known selector |
| `updated_at` | DATETIME | Last update |

### `navigation`

| Column | Type | Description |
|---|---|---|
| `from_url` | VARCHAR | Source page URL |
| `to_url` | VARCHAR | Destination page URL |
| `trigger` | VARCHAR | What caused the navigation (click, submit, etc.) |
| `count` | INT | Times this transition was observed |

### `insights`

| Column | Type | Description |
|---|---|---|
| `category` | ENUM | `selector_tip`, `timing`, `navigation`, `workaround`, `flaky`, `general` |
| `content` | TEXT | The insight text |
| `spec_path` | VARCHAR | Related spec |
| `session_id` | VARCHAR | Session that created it |
| `created_at` | DATETIME | Timestamp |

## Team sync

Memory is local-first. Opt into a shared remote so teammates' learnings flow back:

```bash
# BYO — your S3 / GCS / DoltHub repo / file path
zibby memory remote add aws://my-bucket/team/proj/main
zibby memory remote add gs://bucket/team/proj/main
zibby memory remote add https://www.dolthub.com/repositories/<owner>/<repo>
zibby memory remote add file:///abs/path/to/local-shared

# OR Zibby-managed S3 (no plumbing; signed-in users only)
zibby memory remote use --hosted
```

Once configured:

- `zibby test` auto-pulls before runs and auto-pushes after passing runs
- `zibby memory pull` / `zibby memory push` for manual override
- `zibby memory remote info` to inspect, `zibby memory remote remove` to disconnect

To wire teammates in automatically, set `memorySync.remote` in `.zibby.config.mjs`:

```js
export default {
  agent: { claude: { model: 'auto' } },
  memorySync: {
    remote: 'hosted',                          // or 'aws://my-bucket/team/proj/main' or null
  },
};
```

`zibby init` reads this — when set to `'hosted'` and the user isn't signed in, init prompts for `zibby login` but never blocks. After login, the remote is wired and the next `zibby test` pulls.

### Hosted vs BYO

| | Hosted (`--hosted`) | BYO |
|---|---|---|
| Setup | `zibby memory remote use --hosted` | Provision bucket / IAM / KMS |
| Storage | Zibby-managed AWS account | Your account |
| Access | Anyone with project access on Zibby | Whoever your IAM grants |
| Compliance / data residency | Limited regions | Wherever you want |
| Cost | Included in plan | Your S3 bill |

## Middleware integration

Memory provides automatic middleware that injects history into the node context:

```javascript
import { createMemoryMiddleware } from '@zibby/ui-memory';

const middleware = createMemoryMiddleware();
const graph = new WorkflowGraph({ middleware: [middleware] });
```

The memory skill registers this middleware automatically when `SKILLS.MEMORY` is declared on a node.

## CLI commands

```bash
zibby memory init               # initialize the DB
zibby memory stats              # row counts, last commit, per-spec breakdown
zibby memory cost               # real LLM token spend per spec / per domain
zibby memory compact            # prune old runs + Dolt GC
zibby memory reset -f           # wipe (destructive)
zibby memory pull / push        # manual sync (auto on test start/end if remote configured)
zibby memory remote add <url>   # BYO remote
zibby memory remote use --hosted# Zibby-managed S3
zibby memory remote info        # show config
zibby memory remote remove      # drop the remote
```

## Exports

```javascript
import {
  createMemoryMiddleware,
  memoryEndRun,
  memorySyncPush,
} from '@zibby/ui-memory';
```

## See also

- [`zibby test` recipe](../recipes/test) — the primary consumer of memory
- [Test memory deep dive](../tests/memory) — usage-oriented walkthrough
