git clone --depth 1 https://github.com/Arize-ai/phoenix /tmp/phoenix-sqlean && cp -r /tmp/phoenix-sqlean/.agents/skills/phoenix-sqlean ~/.claude/skills/phoenix-sqleanSKILL.md
# phoenix-sqlean
Vendored fork of [nalgeon/sqlean.py](https://github.com/nalgeon/sqlean.py).
## Bumping a bundled version
Pins live in `packages/phoenix-sqlean/Makefile`. Each has a partner that must move with it:
| Pin | Moves with |
|---|---|
| `SQLITE_VERSION` | `SQLITE_RELEASE_YEAR` (the URL embeds both, so a mismatch 404s) and `SQLITE_SHA256` |
| `SQLEAN_COMMIT` | `SQLEAN_VERSION` in the `Makefile` *and* in `setup.py` — the commit is what gets fetched, the strings only describe it |
| `SQLEAN_VERSION` | `setup.py`'s copy, compiled in as what `sqlean_version()` returns. Suffix `+<short sha>` iff `SQLEAN_COMMIT` sits ahead of the named tag |
| `XXHASH_TAG` | `XXHASH_COMMIT` + `XXHASH_SHA256`, and the tag sqlean's own `Makefile` fetches |
`check-sqlean-pin`, a prerequisite of `download-sqlean`, enforces the `SQLEAN_*` rows for one
`ls-remote`: suffix prefixes the commit, base is a real tag, suffix present iff ahead, `setup.py`
agrees. It cannot tell you the base names the *wrong* release — the single-commit fetch carries no
ancestry. `SQLITE_*` and `XXHASH_*` get no equivalent cross-check — only their hashes, at fetch.
sqlean is fetched over git by commit: GitHub's source archives are generated on demand and not
byte-stable, so they cannot be checksum-pinned, while git hashes every object it receives. Hence
`download-sqlean` needs `git` on PATH and no checksum. The other two arrive over plain HTTP, where
curl verifies nothing — `XXHASH_COMMIT` fixes which bytes are correct and `XXHASH_SHA256` proves
they are those. `src/test_windirent.h` needs neither; it is committed to this repo.
### With the script
`scripts/check-upstream.sh` resolves and rewrites every pin, hashes included:
```bash
cd packages/phoenix-sqlean
./scripts/check-upstream.sh sqlite # detection only, no downloads
./scripts/check-upstream.sh sqlite --apply # rewrite pins, print a Markdown summary
./scripts/check-upstream.sh sqlean [--apply] # also moves XXHASH_* if sqlean moved its own
```
### By hand
Resolve a tag to a commit with `git ls-remote <repo> 'refs/tags/<version>*'`, taking the peeled
`^{}` line when the tag is annotated. sqlean also carries a non-version tag (`incubator`), so
filter by shape before picking a latest.
For `SQLITE_SHA256`, confirm the download against the SHA3-256 in the `PRODUCT` line on
<https://sqlite.org/download.html> *before* recording the SHA-256 (`shasum` cannot do SHA3).
Skipping that makes the pin trust-on-first-use.
### Verify
```bash
cd packages/phoenix-sqlean
make prepare-src download-sqlite download-sqlean # always the full chain: download-sqlean
# APPENDS init.c, so alone it double-appends
python setup.py build_ext -i
python -m tests
```
## Staying current
Dependabot cannot see these pins — no custom-regex manager — and there is no Renovate here.
`phoenix-sqlean-upstream.yml` fills the gap: weekly, one draft PR per component, running
`check-upstream.sh --apply`, no model involved.
**It builds and tests nothing.** CI covers that on the PR; verifying inside the bump job would
re-run a subset of it, on the one platform where the likeliest failure — `patch(1)` on the MSVC
patch — cannot reproduce.
A failure of the script itself is different: upstream changed shape, so it exits before writing and
the job goes red with no PR, because there is no computed bump to review.
`XXHASH_*` is deliberately unwatched. sqlean drives it, and `download-sqlean` already fails when
sqlean moves its own pin.
## Gotchas
- **`src/test_windirent.h` is pinned at 3.50.4 — do not re-sync it.** SQLite removed it in 3.51.0
and no newer tag has it. Vendored deliberately, not downloaded.
- **sqlean >= 0.28 needs `crypto/xxhash.impl.h`, which sqlean does not ship.** Any new third-party
source needs a `THIRD_PARTY_LICENSES` section *and* its SPDX identifier in `license=`.
- **`patch(1)` failing on `src/sqlean-time-msvc.patch` is the intended tripwire**, not a breakage.
Regenerate it against the new sqlean sources.
- **"sqlean fetches xxHash X, but XXHASH_TAG is Y" is the other one.** Move all three `XXHASH_*`
pins, and the version named in `THIRD_PARTY_LICENSES`.
- **The `sqlean_version()` test is a tautology on its own** — it compares the compiled macro to
`setup.py`'s own constant, proving only that the binary is not stale. `check-sqlean-pin` is what
ties that constant back to `SQLEAN_COMMIT`.
- **Changing `SQLEAN_VERSION` alone does not trigger a recompile.** It only moves a `-D` flag, and
`build_ext` keys on source mtime. `touch src/sqlean.c` after editing, or the version test fails
against a merely stale build.
- **Keep the package version plain SemVer.** release-please's version regex is unanchored, so
`3.53.4.1` and `3.53.4.post1` truncate to `3.53.4` and collide with an existing tag, silently.
For the same reason `VERSION` must stay above `SQLEAN_VERSION` in `setup.py`. The package version
is intentionally independent of the bundled SQLite version.
## Wheels and publishing
- Settings are in `cibuildwheel.toml`, steps in `phoenix-sqlean-build.yml` — a `workflow_call`
workflow that both `build-sqlean` in `publish.yaml` and CI's `wheel` job invoke, so a PR runs
the build a release runs.
- The matrix is cp310–cp314 across Linux x86_64/aarch64, macOS x86_64/arm64, Windows AMD64/ARM64,
plus an sdist of the C sources. A misspelled key in the toml errors; a misspelled `CIBW_*` env
var is a silent no-op.
- **An empty `CIBW_*` is an override, not a no-op.** It replaces the toml's value with
cibuildwheel's own default — Linux goes from 10 identifiers to 36, musllinux and free-threaded
included. Hence the `cibw-*` inputs reach the environment only when non-empty.
- **`test-sources` resolves against cibuildwheel's working directory, not `package-dir`** — hence
the workspace-root unpack, which the shared workflow puts under CI.
- CI's `test` matrix compiles in place across every OS/arch pair the puBrowser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
Build and maintain documentation sites with Mintlify. Use when creating docs pages, configuring navigation, adding components, or setting up API references.
Debug LLM applications using the Phoenix CLI. Fetch traces, analyze errors, structure trace review with open coding and axial coding, inspect datasets, review experiments, query annotation configs, and use the GraphQL API. Use whenever the user is analyzing traces or spans, investigating LLM/agent failures, deciding what to do after instrumenting an app, building failure taxonomies, choosing what evals to write, or asking "what's going wrong", "what kinds of mistakes", or "where do I focus" — even without naming a technique.
Design system conventions for the Phoenix frontend — layout, dialogs, error display, BEM CSS class naming, and CSS design tokens. Use when building UI, naming CSS classes, creating or consuming tokens, handling errors, or designing dialog interactions in js/app/src/.
>
>-
Build and run evaluators for AI/LLM applications using Phoenix.
Frontend development guidelines for the Phoenix AI observability platform. Use when writing, reviewing, or modifying React components, TypeScript code, styles, or UI features in the js/app/ directory. Triggers on any frontend task — new components, UI changes, styling, accessibility fixes, form handling, or component refactoring. Also use when the user asks about frontend conventions or component patterns for this project. For design system rules (error display, layout, dialogs, tokens), use the phoenix-design skill.