AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Agent Memory

skill-code-saurabh-openskills-agent-memory · by CODE-SAURABH

Session memory management, browser-based QA testing, and multi-agent coordination skill. Use when the user wants to persist learnings across sessions, review what the agent has learned about their codebase, prune stale knowledge, run browser-based testing with real Chromium, coordinate multiple AI agents on the same task, or set up authenticated browser sessions for testing.

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-code-saurabh-openskills-agent-memory

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-code-saurabh-openskills-agent-memory)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Agent Memory? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Agent Memory — Unified Skill

This skill unifies three complementary capabilities into a single, coherent workflow:

  1. /learn — Session Memory Management — Persist, search, prune, and export what the agent has learned about your codebase and project across sessions.
  2. /browse — Browser-Based QA Testing — Drive real Chromium (headless or headed), click elements, take screenshots, import cookies, and assert page state for production-grade QA.
  3. /pair-agent — Multi-Agent Coordination — Spawn parallel sub-agents on isolated scopes, aggregate results, and hand off context cleanly between agents.

Part 1 — Memory Management (/learn)

1.1 Philosophy: Why Memory Matters

Every time the agent explores your codebase, it discovers implicit patterns that are expensive to rediscover:

  • Which modules are load-bearing vs. experimental
  • Naming conventions that are project-local (not language-default)
  • Fragile integration points that have broken before
  • Performance invariants the team cares about
  • Domain-specific jargon used in comments and variable names

Without memory, the agent starts cold every session. With memory, compound knowledge accumulates — each session builds on prior sessions, reducing repeated archaeology and increasing the precision of every suggestion.

Principle: Memory is a first-class engineering artifact. Treat it like documentation.


1.2 Memory Scopes

There are two distinct scopes of memory. Always be explicit about which scope you are reading from or writing to.

Global Memory (~/.agent-memory/global/)

Stores patterns that apply across all projects on this machine:

  • Preferred code style decisions (e.g., "always use early-return guards")
  • Recurring architectural preferences (e.g., "prefer repository pattern over active record")
  • User-level shortcuts and workflow preferences
  • Learned tool behaviors (e.g., "this user's Makefile uses make lint not make check")
Project Memory (/.agent-memory/)

Stores patterns specific to the current repository:

  • Module ownership and dependency graph insights
  • Known flaky test files and their workarounds
  • Environment setup quirks (e.g., "must source .env.local before running tests")
  • API contracts with external services this codebase integrates with
  • Domain concepts: entity names, lifecycle states, event vocabulary
  • Historical bugs and their root causes (for future regression awareness)
  • Architecture Decision Records (ADRs) that affect code shape

Rule: If a pattern applies only to one repo, it MUST be written to project memory, not global. Polluting global memory with project-specific facts degrades the signal-to-noise ratio for all projects.


1.3 Memory File Format

All memory entries are stored as structured Markdown files for human readability and diff-friendliness.

.agent-memory/
├── patterns/
│   ├── naming-conventions.md
│   ├── architecture.md
│   ├── testing-patterns.md
│   └── fragile-zones.md
├── domains/
│   ├── entities.md
│   └── events.md
├── history/
│   ├── bugs-resolved.md
│   └── refactors-completed.md
└── index.md          ← master index with dates and tags

Each entry in a memory file follows this schema:

## [PATTERN_ID] Short Title

**Learned:** YYYY-MM-DD  
**Confidence:** high | medium | low  
**Scope:** global | project  
**Tags:** #architecture #naming #performance  
**Source:** session-id or description of how this was discovered  

### Observation
What was observed.

### Pattern
The generalizable rule extracted from the observation.

### Example
Concrete code or command example.

### Caveats
Conditions under which this pattern does NOT apply.

1.4 Writing New Memory

When you discover something worth remembering, write it immediately — not at the end of the session, because sessions can be interrupted.

Trigger conditions for writing a new memory entry:

  • You found a non-obvious architectural invariant (e.g., "all writes go through the event bus, never direct DB calls")
  • You discovered a project-specific naming rule not in any README
  • You debugged a recurring error class and want to short-circuit future debugging
  • You learned how the build system behaves in an undocumented edge case
  • The user explicitly says "remember this" or "add this to memory"

Writing procedure:

# 1. Determine scope
SCOPE="project"  # or "global"

# 2. Determine the correct category file
CATEGORY="patterns/architecture"  # or naming-conventions, testing-patterns, etc.

# 3. Generate a unique pattern ID
PATTERN_ID="ARCH-$(date +%Y%m%d)-001"

# 4. Write the entry (append to the category file)
# Use the schema defined in section 1.3 above.

# 5. Update the index
echo "- [$PATTERN_ID] Short title — $CATEGORY — $(date +%Y-%m-%d)" >> .agent-memory/index.md

1.5 Reading and Reviewing Memory

At the START of every session on a known project, load the memory index and the relevant category files before making any code suggestions.

# Load the project memory index
cat .agent-memory/index.md 2>/dev/null || echo "No project memory yet."

# Load global memory index
cat ~/.agent-memory/global/index.md 2>/dev/null || echo "No global memory yet."

When the user asks to review memory:

  1. Print the full index with IDs, titles, dates, and tags.
  2. Group entries by category (patterns, domains, history).
  3. Flag entries older than 90 days as "⚠️ Stale — review for pruning."
  4. Flag entries with Confidence: low as "🔍 Uncertain — verify before relying on."

1.6 Searching Memory

When the user asks to search memory for a topic:

# Search all memory files for a keyword
grep -r "KEYWORD" .agent-memory/ --include="*.md" -l

# Search with context lines
grep -r "KEYWORD" .agent-memory/ --include="*.md" -n -B 2 -A 4

Search is case-insensitive by default. Present results grouped by file, with the pattern ID and title prominently displayed.


1.7 Pruning Memory

Memory must be pruned to stay useful. Stale or wrong memory is worse than no memory — it misleads future sessions.

Prune when:

  • A refactor changed the architectural pattern the entry described
  • A dependency was removed (its patterns are now irrelevant)
  • An entry is >180 days old and hasn't been referenced or validated
  • The user explicitly says "this is no longer true"
  • The confidence level was low and it never got validated

Prune procedure:

# 1. List entries older than 90 days
find .agent-memory/ -name "*.md" -mtime +90

# 2. For each candidate, present to user for confirm/keep/update
# 3. Delete confirmed-stale entries
# 4. Remove from index.md
# 5. Commit the pruning as a standalone commit with message:
#    "chore(memory): prune stale entries — YYYY-MM-DD"

Never silently delete memory. Always show the user what will be removed and get confirmation (or use --force flag only if user explicitly requests unattended pruning).


1.8 Exporting Memory

When the user wants to export memory (e.g., to share with a new team member, or to seed a new project):

# Export as a single consolidated Markdown document
cat .agent-memory/**/*.md > memory-export-$(date +%Y%m%d).md

# Export as JSON for programmatic use
python3 -c "
import os, json, re
from pathlib import Path

entries = []
for f in Path('.agent-memory').rglob('*.md'):
    content = f.read_text()
    entries.append({'file': str(f), 'content': content})

print(json.dumps(entries, indent=2))
" > memory-export-$(date +%Y%m%d).json

1.9 How Learnings Compound Across Sessions

The compounding effect works as follows:

| Session | What Happens | |---------|--------------| | 1 | Agent discovers project structure, writes 3–5 foundational entries | | 2 | Agent loads index, skips re-exploration, writes 2–3 deeper entries | | 3 | Agent cross-references existing patterns, catches inconsistencies | | 5+ | Agent predicts issues before the user encounters them | | 10+ | Agent functions like a senior team member who knows the codebase |

Key behaviors that enable compounding:

  • Always load memory at session start (not on demand)
  • Cross-reference new discoveries against existing entries before writing duplicates
  • Upgrade confidence levels when an entry is validated a second time
  • Link related entries using [PATTERN_ID] references within entries

Part 2 — Browser QA Testing (/browse)

2.1 Philosophy

Real QA requires a real browser. Mocks and unit tests cannot catch:

  • Layout regressions caused by CSS specificity conflicts
  • Race conditions in JavaScript initialization
  • Server-side rendering hydration mismatches
  • Authentication flows that depend on session cookies
  • Third-party widget interactions (analytics, chat widgets, payment iframes)

This skill drives real Chromium via Playwright, giving you pixel-accurate, JS-executing, network-real browser automation.


2.2 Prerequisites and Setup

# Install Playwright with Chromium
pip install playwright
playwright install chromium

# Or via npm
npm install -D playwright
npx playwright install chromium

# Verify installation
python3 -c "from playwright.sync_api import sync_playwright; print('Playwright OK')"

2.3 Basic Navigation and Screenshot

from playwright.sync_api import sync_playwright
import os

def browse_and_screenshot(url: str, output_path: str = "screenshot.png"):
    """
    Navigate to a URL and capture a full-page screenshot.
    Uses stealth settings to avoid bot detection.
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=True,
            args=[
                "--no-sandbox",
                "--disable-setuid-sandbox",
                "--disable-blink-features=AutomationControlled",
                "--disable-dev-shm-usage",
                "--disable-accelerated-2d-canvas",
                "--no-first-run",
                "--no-zygote",
                "--disable-gpu",
            ]
        )

        context = browser.new_context(
            viewport={"width": 1440, "height": 900},
            user_agent=(
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/120.0.0.0 Safari/537.36"
            ),
            locale="en-US",
            timezone_id="America/New_York",
        )

        # Anti-bot: remove webdriver property
        context.add_init_script("""
            Object.defineProperty(navigator, 'webdriver', {
                get: () => undefined,
            });
        """)

        page = context.new_page()
        page.goto(url, wait_until="networkidle", timeout=30000)
        page.screenshot(path=output_path, full_page=True)
        browser.close()
        print(f"Screenshot saved to {output_path}")

browse_and_screenshot("https://localhost:3000", "qa-screenshot.png")

2.4 Real Clicks and Form Interactions

def test_login_flow(base_url: str, email: str, password: str):
    """
    Test a real login flow with form filling and navigation assertions.
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(f"{base_url}/login")

        # Fill form fields
        page.fill('input[name="email"]', email)
        page.fill('input[name="password"]', password)

        # Screenshot before submit (for debugging)
        page.screenshot(path="before-login.png")

        # Click submit and wait for navigation
        with page.expect_navigation(wait_until="networkidle"):
            page.click('button[type="submit"]')

        # Assert post-login destination
        assert "/dashboard" in page.url, f"Expected redirect to /dashboard, got {page.url}"

        # Assert key element is present
        page.wait_for_selector('[data-testid="welcome-message"]', timeout=5000)

        # Screenshot after login
        page.screenshot(path="after-login.png")
        browser.close()
        print("Login flow: PASS")

2.5 Anti-Bot Stealth Configuration

For sites with advanced bot detection (Cloudflare, Akamai, DataDome):

def stealth_context(playwright_instance):
    """
    Create a maximum-stealth browser context.
    Mimics a real macOS Chrome user as closely as possible.
    """
    browser = playwright_instance.chromium.launch(
        headless=True,
        args=[
            "--disable-blink-features=AutomationControlled",
            "--disable-features=IsolateOrigins,site-per-process",
        ]
    )

    context = browser.new_context(
        viewport={"width": 1440, "height": 900},
        screen={"width": 1440, "height": 900},
        user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        locale="en-US",
        timezone_id="America/Los_Angeles",
        color_scheme="light",
        device_scale_factor=2.0,  # Retina display
        has_touch=False,
        java_script_enabled=True,
        accept_downloads=True,
        extra_http_headers={
            "Accept-Language": "en-US,en;q=0.9",
            "Accept-Encoding": "gzip, deflate, br",
        }
    )

    # Remove all automation fingerprints
    context.add_init_script("""
        // Hide webdriver
        Object.defineProperty(navigator, 'webdriver', { get: () => undefined });

        // Fake plugins
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5],
        });

        // Fake languages
        Object.defineProperty(navigator, 'languages', {
            get: () => ['en-US', 'en'],
        });

        // Hide Chrome automation
        window.chrome = { runtime: {} };

        // Fake permissions
        const originalQuery = window.navigator.permissions.query;
        window.navigator.permissions.query = (parameters) => (
            parameters.name === 'notifications'
                ? Promise.resolve({ state: Notification.permission })
                : originalQuery(parameters)
        );
    """)

    return browser, context

2.6 Cookie Import from Real Browser

To test authenticated sessions without re-logging in via automation (which often triggers 2FA):

Step 1: Export cookies from your real browser

Use the browser extension "Cookie-Editor" (Chrome/Firefox) to export cookies as JSON, or use the EditThisCookie extension.

Alternatively, export from Chrome's profile directly:

# macOS — copy Chrome's cookies database (requires Chrome to be closed)
cp ~/Library/Application\ Support/Google/Chrome/Default/Cookies /tmp/chrome-cookies.db

# Extract cookies for a specific domain using sqlite3
sqlite3 /tmp/chrome-cookies.db \
  "SELECT host_key, name, value, path, expires_utc, is_secure, is_httponly
   FROM cookies WHERE host_key LIKE '%yourdomain.com%';"
Step 2: Load cookies into Playwright context
import json

def load_cookies_from_file(context, cookie_file: str):
    """
    Load cookies exported from a real browser into a Playwright context.
    Supports the Cookie-Editor JSON export format.
    """
    with open(cookie_file) as f:
        raw_cookies = json.load(f)

    playwright_cookies = []
    for c in raw_cookies:
        cookie = {
            "name": c["name"],
            "value": c["value"],
            "domain": c.get("domain", ""),
            "path": c.get("path", "/"),
            "secure": c.get("secure", False),
            "httpOnly": c.get("httpOnly", False),
        }
        # Handle expiry
        if "expirationDate" in c:
            cookie["expires"] = int(c["expirationDate"])

        playwright_cookies.append(cookie)

    context.add_cookies(playwright_cookies)
    print(f"Loaded {len(playwright_cookies)} cookies.")

# Usage
with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context()
    load

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [CODE-SAURABH](https://github.com/CODE-SAURABH)
- **Source:** [CODE-SAURABH/OpenSkills](https://github.com/CODE-SAURABH/OpenSkills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.