Skip to main content
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 )
ComponentExample
actionaction/click
urlOriginhttps://example.com
selectorHintrole: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 toCSS selector stored
Element with id#submit-btn (escaped via CSS.escape())
Element with data-testid[data-testid="submit-button"]
Other elementsNot cached (intentional)
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.

Cache Entry Structure

{
  "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

OptionDefaultDescription
dir~/.bap/cache/actionsCache directory
enabledtrueEnable/disable caching
ttl86400 (24 hours)Time-to-live in seconds
maxEntries1000Maximum entries before LRU eviction

Invalidation

The cache is invalidated in three ways:
1

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.
2

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.
3

LRU eviction

When the cache exceeds maxEntries (default 1000), the oldest entry by creation time is evicted.

Cache Stats

The ActionCache class exposes a stats() method:
const stats = cache.stats();
// { entries: 47, hits: 312, dir: "/Users/you/.bap/cache/actions" }

Workflow Integration

The action cache integrates with 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:
# Clear all cached selectors
rm -rf ~/.bap/cache/actions/

# Clear workflow manifests
rm -rf ~/.bap/cache/workflows/
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.