> ## Documentation Index
> Fetch the complete documentation index at: https://piyushvyas.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Action Cache

> File-system LRU cache for instant selector resolution on repeat workflows

The action cache stores successful selector resolutions on disk so that repeat workflows skip DOM traversal entirely. When BAP resolves a semantic selector like `role:button:"Submit"` to a concrete CSS selector like `#submit-btn`, it caches that mapping for future use.

## How It Works

```
First run:
  role:button:"Submit" → DOM traversal → finds #submit-btn → caches it

Second run:
  role:button:"Submit" → cache hit → #submit-btn → direct CSS lookup (no traversal)
```

The cache uses a file-system LRU strategy at `~/.bap/cache/actions/`. Each entry is a JSON file named by its SHA256 key.

## Cache Key

Keys are generated from three components:

```
SHA256( action | urlOrigin | selectorHint )
```

| Component      | Example                |
| -------------- | ---------------------- |
| `action`       | `action/click`         |
| `urlOrigin`    | `https://example.com`  |
| `selectorHint` | `role:button:"Submit"` |

This means the same selector on different sites gets different cache entries, and the same selector with different actions (click vs hover) is also cached separately.

## What Gets Cached

The cache stores resolved CSS selectors, not the original semantic selectors:

| Resolved to                | CSS selector stored                        |
| -------------------------- | ------------------------------------------ |
| Element with `id`          | `#submit-btn` (escaped via `CSS.escape()`) |
| Element with `data-testid` | `[data-testid="submit-button"]`            |
| Other elements             | Not cached (intentional)                   |

<Info>
  Only elements with an `id` or `data-testid` attribute are cached. This is intentional -- these are
  the most stable identifiers. Elements without them rely on semantic resolution each time.
</Info>

## Cache Entry Structure

```json theme={null}
{
  "key": "a1b2c3d4e5f6g7h8",
  "action": "action/click",
  "instruction": "Click the submit button",
  "resolvedSelector": {
    "type": "css",
    "value": "#submit-btn"
  },
  "urlPattern": "https://example.com",
  "domFingerprint": "f8e7d6c5b4a3",
  "createdAt": 1711036800000,
  "hitCount": 12,
  "ttl": 86400000
}
```

## Configuration

| Option       | Default                | Description                         |
| ------------ | ---------------------- | ----------------------------------- |
| `dir`        | `~/.bap/cache/actions` | Cache directory                     |
| `enabled`    | `true`                 | Enable/disable caching              |
| `ttl`        | `86400` (24 hours)     | Time-to-live in seconds             |
| `maxEntries` | `1000`                 | Maximum entries before LRU eviction |

## Invalidation

The cache is invalidated in three ways:

<Steps>
  <Step title="TTL expiry">
    Entries older than 24 hours (default) are removed on next access. Expired entries are also cleaned up when the cache loads from disk.
  </Step>

  <Step title="Selector failure">
    If a cached CSS selector fails to match (element was removed or ID changed), the cache entry is
    deleted immediately. The server falls back to fresh semantic resolution.
  </Step>

  <Step title="LRU eviction">
    When the cache exceeds `maxEntries` (default 1000), the oldest entry by creation time is evicted.
  </Step>
</Steps>

## Cache Stats

The `ActionCache` class exposes a `stats()` method:

```typescript theme={null}
const stats = cache.stats();
// { entries: 47, hits: 312, dir: "/Users/you/.bap/cache/actions" }
```

## Workflow Integration

The action cache integrates with [workflow fusion](/concepts/workflow-fusion). After a successful `bap run`, a cache manifest is saved that tracks which cache entries were used. This enables:

* **Cache warmth checks**: `bap run <name> --dry-run` reports how many selectors are already cached
* **Selective invalidation**: If the workflow YAML changes (different SHA256), the manifest is regenerated on next run
* **Performance tracking**: Batch timings are stored in the manifest for trend analysis

## Manual Cache Management

The cache lives at `~/.bap/cache/actions/` as individual JSON files. To clear it:

```bash theme={null}
# Clear all cached selectors
rm -rf ~/.bap/cache/actions/

# Clear workflow manifests
rm -rf ~/.bap/cache/workflows/
```

<Tip>
  The cache is best-effort. If the directory is not writable or a file is corrupt, BAP falls back to
  fresh resolution without error. You never need to manage the cache manually.
</Tip>
