<!-- BEGIN zibby-workflows zibby-template-version: 4 -->
## Zibby

This project uses **Zibby** — there are two surfaces:

1. **Agents** — graphs of AI-agent-driven steps that run in a sandboxed container, on Zibby Cloud or on your self-hosted box. Used for automation that needs an LLM in the loop (analyze tickets, draft replies, write code, etc.).

2. **Tests** — plain-language `.txt` specs that Zibby's runner converts to Playwright executions. Produces video + JSON results. Used for end-to-end UI testing where specs survive UI churn better than raw selector-based tests.

Both share `.zibby.config.mjs` at the project root.

---

### Agents

Files:
```
<paths.agents or .zibby/workflows>/<name>/
├── agent.json    name, entryClass, triggers, schemas (manifest)
├── graph.mjs        nodes + edges from START to END
├── nodes/
│   ├── index.mjs    barrel export
│   └── *.mjs        one node per file: { id, description, run(ctx) }
└── package.json     deps; bundled at deploy time
```

Each node has `async run(ctx)` where `ctx` provides:
- `ctx.input` — outputs from upstream nodes
- `ctx.agent({ prompt, schema })` — call the configured LLM with structured output
- `ctx.shell(cmd)` — run shell in the sandbox (egress proxy enabled)
- `ctx.log(...)` — emit a log line (visible via `zibby agent logs`)

Common dev loop:
```
zibby agent new <name>               # scaffold
zibby agent run <name>               # one-shot local run (preferred for the dev loop)
zibby agent run <name> -p k=v        # with input
zibby agent deploy <name>            # build + push to Zibby Cloud
zibby agent trigger <uuid>           # invoke the cloud agent
zibby agent logs <uuid> -t           # tail live logs (docker-compose-style)
zibby agent list                     # find UUIDs and statuses (local + cloud)
zibby agent download <uuid>          # pull the cloud agent source back to .zibby/workflows/
zibby agent delete <uuid>            # remove a deployed agent
```

**`run` vs `start`.** `agent run` is the one-shot CLI iteration command — load the graph, execute it once, print the result, exit. That's the right primitive for the dev loop and for CI/CD. `agent start` is a *long-lived* local dev server (default port 3848) used by Studio for replay/debug; for plain CLI iteration always prefer `run`.

`run` and `trigger` accept the same input flag surface — flip the verb to switch between local and cloud:
- `-p key=value` (repeatable) — highest precedence
- `--input '<json>'` — JSON string
- `--input-file path.json` — JSON file, lowest precedence

Static outbound IPs (for customers behind firewalls): see `--dedicated-ip` flag on `deploy`.

#### Per-agent env vars

Each deployed agent has its own encrypted env-var bag. Vars get injected into the task at trigger time, and **agent env wins over project secrets on conflict**. Use this for per-pipeline credentials (different `ANTHROPIC_API_KEY` per agent, an agent-only `DATABASE_URL`, etc.).

```
zibby agent env list <uuid>                          # show key names (values never returned)
zibby agent env set  <uuid> ANTHROPIC_API_KEY=sk-…   # add or rotate one key
zibby agent env unset <uuid> OLD_KEY                 # remove one key
zibby agent env push <uuid> --file .env [--file .env.prod]   # bulk replace from .env files
```

Fast path on first deploy — sync a `.env` in one shot:
```
zibby agent deploy my-pipeline --env .env [--env .env.prod]
```
The CLI deploys, then runs `push` against the freshly-minted UUID.

---

### Tests

Files:
```
test-specs/                 source `.txt` specs (paths.specs)
tests/                      generated `.spec.js` (paths.generated; regenerated each run)
test-results/               videos, traces, JSON results per run
.zibby/memory/.dolt/        local test memory DB (selectors, page model, history)
playwright.config.js
```

A spec is plain-language imperative English describing what to test. Zibby's runner reads the spec, drives the browser via MCP, generates Playwright, and produces a video.

Common dev loop:
```
zibby test test-specs/<name>.txt        # run a spec
zibby test "go to example.com and ..."  # inline, no file
zibby test <spec> --agent claude        # override the configured agent (claude|cursor|codex|gemini)
zibby test --sources <ids> --execution <id>   # cloud test cases (run from a stored execution)
zibby generate -t ENG-1234              # generate specs from a Jira ticket
zibby video                             # organize videos next to spec files
zibby upload <spec-path>                # upload existing artifacts to cloud
```

When debugging a failed test, watch the video at `test-results/<spec>/video.webm` — that's almost always faster than reading logs.

#### Test memory

`.zibby/memory/.dolt/` is a **local-first Dolt SQL database** (Git-for-data) that learns from every test run — selectors that worked, page-element fingerprints, navigation transitions, timing quirks, recorded insights. The runner auto-pulls before a run and auto-pushes after a passing run. Keying is **per-domain** (not per-spec), so any spec that hits `myapp.com` benefits from selectors learned by every other spec on the same domain.

When `zibby test` runs and `.zibby/memory/.dolt/` exists, the agent gets 5 MCP tools auto-exposed:

- `memory_get_test_history` — query recent runs (pass/fail/timing); filter by spec-path substring
- `memory_get_selectors` — query known selectors per page with stability metrics (success/fail counts)
- `memory_get_page_model` — query page structure (elements, roles, accessible names, best selector)
- `memory_get_navigation` — known page-to-page transitions (what click/submit produced what URL)
- `memory_save_insight` — save an observation. Categories: `selector_tip | timing | navigation | workaround | flaky | general`

> **AFTER completing the test, you MUST call `memory_save_insight` at least once.** Save any useful finding: reliable selectors, timing quirks, navigation patterns, workarounds. Be specific — future runs will read your insights. (Lifted from the memory skill's `promptFragment`.)

Local CLI:
```
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 (--max-runs 50, --max-age 90d)
zibby memory reset -f      # wipe the DB
```

**Team sync.** Memory is local-first; opt into a shared remote so teammates' learnings flow back to you:

```
zibby memory remote add aws://my-bucket/team/proj/main   # BYO S3 / GCS / DoltHub / file:///
zibby memory remote use --hosted                         # OR: Zibby-managed S3 (signed-in only)
zibby memory pull                                        # manual override (auto on test start)
zibby memory push                                        # manual override (auto on passing test)
```

Set `memorySync.remote` in `.zibby.config.mjs` (`'hosted'` or an `aws://...` URL) and `zibby init` auto-wires the remote — teammates clone the repo, run `zibby init`, and they're plugged into the same memory.

---

### How to invoke the CLI

The `zibby` command might be on PATH (if installed globally via npm) OR not — depending on the user's setup. **If `zibby` returns "command not found", fall back to `./.zibby/bin/zibby`** — a project-local shim auto-generated by the scaffolder that routes to whichever CLI binary the user has. Always exists in this project.

```
# Try first:
zibby agent list

# If "command not found":
./.zibby/bin/zibby agent list
```

Don't waste time on `npx @zibby/cli` — not always published.

---

### Reference (always prefer canonical docs over these notes)

**Agents**
- Concepts: https://docs.zibby.app/workflows
- Node SDK (ctx.*): https://docs.zibby.app/workflows/sdk
- Deploying & bundling: https://docs.zibby.app/workflows/deploying
- Triggering & inputs: https://docs.zibby.app/workflows/triggers
- Live log streaming: https://docs.zibby.app/workflows/logs
- Per-workflow env vars: https://docs.zibby.app/cloud/env-vars
- Egress proxy / static IPs: https://docs.zibby.app/workflows/egress
- Security & secrets: https://docs.zibby.app/workflows/security
- Debugging: https://docs.zibby.app/workflows/debugging

**Tests**
- Spec format: https://docs.zibby.app/tests/specs
- Running (`zibby test`): https://docs.zibby.app/tests/running
- Generating from Jira: https://docs.zibby.app/tests/generating
- Test memory: https://docs.zibby.app/tests/memory
- Debugging: https://docs.zibby.app/tests/debugging
- MCP browser config: https://docs.zibby.app/tests/playwright-mcp

When in doubt about behavior, fetch the docs URL — these notes are a snapshot, the docs are kept current.
<!-- END zibby-workflows -->
