Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "pgrundev",
"description": "PostgreSQL developer tools for AI coding agents",
"owner": {
"name": "PGRunDev",
"url": "https://pgx.dev"
},
"plugins": [
{
"name": "pgx",
"source": "./plugins/pgx",
"description": "Give every AI coding agent its own isolated, disposable Postgres database.",
"category": "database",
"tags": ["postgres", "postgresql", "database", "ai-agents", "database-branching"],
"homepage": "https://github.com/pgrundev/pgx"
}
]
}
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ jobs:
npx -y skills@latest add "$GITHUB_WORKSPACE/skills/pgx" -a claude-code codex cursor -y
test -f .claude/skills/pgx/SKILL.md && test -f .agents/skills/pgx/SKILL.md
test ! -e .claude/skills/pgx/tests
plugin:
name: Claude Code plugin (marketplace, manifest, install cycle)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- name: Install the Claude Code CLI (pinned; validate/install need no login)
run: npm install -g @anthropic-ai/claude-code@2.1.310 && claude --version
- name: Plugin package tests (drift, manifests, hygiene, isolated install cycle)
run: plugins/tests/pgx/run.sh
- name: Secret scan of the plugin package and marketplace (gitleaks)
run: |
curl -fsSL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz gitleaks
for d in plugins .claude-plugin skills; do ./gitleaks dir "$d" --no-banner --redact; done
docker:
name: Docker image (${{ matrix.os }})
strategy:
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@
<a href="LICENSE"><img alt="License: AGPL-3.0" src="https://img.shields.io/badge/license-AGPL--3.0-blue"></a>
</p>

```text
# Claude Code: install inside a session (native plugin)
/plugin marketplace add pgrundev/pgx
/plugin install pgx@pgrundev
```

```bash
# Recommended: AI coding agents (Claude Code, Cursor, Codex)
# Any agent host (Claude Code, Cursor, Codex): the Agent Skills CLI
npx skills add pgrundev/pgx --skill pgx

# Manual PGX installation
Expand Down Expand Up @@ -396,14 +402,31 @@ permanent or system databases, and resumes cleanup automatically after a

### Every AI agent gets its own Postgres

Install the Skill in a project, then ask your agent:
Install the Skill, then ask your agent. In Claude Code, from inside a session:

```text
/plugin marketplace add pgrundev/pgx
/plugin install pgx@pgrundev
/pgx:pgx Set up isolated Postgres databases for this project.
```

For Cursor, Codex or several hosts at once, the Agent Skills CLI installs the
same Skill into the project:

```bash
npx skills add pgrundev/pgx --skill pgx
```

> Use PGX to give this project isolated databases for coding agents. Set everything up.

The plugin is the Skill packaged for Claude Code's plugin manager (`/plugin`
lists, updates and removes it; the skill is `/pgx:pgx` and Claude also picks
it up on its own when a task touches the database). The Skills CLI copies
the Skill into `.claude/skills/pgx` and `.agents/skills/pgx` for every host.
Both contain no hooks and install no database engine: the `pgx` binary is
installed when the Skill first needs it, with your approval. Details and the
differences: [`docs/pgx/local-dev/claude-plugin.md`](docs/pgx/local-dev/claude-plugin.md).

The agent detects your database setup, installs PGX if needed, imports your
development database **schema-only** into a template (`pgx copy`), writes a
committed `.pgx.toml`, installs lifecycle hooks (`pgx agent setup`) and
Expand Down Expand Up @@ -563,6 +586,7 @@ any semantic difference (`classify-regress-diffs.py --fail-on-semantic`).
| [`v0.1-readiness.md`](docs/pgx/v0.1-readiness.md) | what is ready, known limitations, approved use |
| [`linux-results.md`](docs/pgx/linux-results.md) | the full benchmark report |
| [`compatibility-gate.md`](docs/pgx/compatibility-gate.md) | how to decide whether a database can run on PGX |
| [`local-dev/claude-plugin.md`](docs/pgx/local-dev/claude-plugin.md) | the PGX plugin for Claude Code: `/plugin marketplace add pgrundev/pgx`, `/plugin install pgx@pgrundev`, how it relates to the Skills CLI install, updates, removal |
| [`local-dev/agents.md`](docs/pgx/local-dev/agents.md) | the PGX Skill and `pgx agent`: automatic per-session isolation for Claude Code, Cursor and Codex, with the compatibility matrix |
| [`local-dev/copy.md`](docs/pgx/local-dev/copy.md) | `pgx copy`: import an existing PostgreSQL database and branch it per agent |
| [`pgrun-integration.md`](docs/pgx/pgrun-integration.md) | the host-agent API PGRun builds against |
Expand Down
17 changes: 15 additions & 2 deletions docs/pgx/local-dev/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@ Code, Cursor or Codex session that touches your database works in its own
disposable branch of a template, created in milliseconds, never shared, and
cleaned up on its own. Your real PostgreSQL is read once and never written.

```text
/plugin marketplace add pgrundev/pgx # Claude Code: the Skill as a native plugin, inside a session
/plugin install pgx@pgrundev
```

```sh
npx skills add pgrundev/pgx --skill pgx # the Skill (recommended)
npx skills add pgrundev/pgx --skill pgx # any host (Claude Code, Cursor, Codex): the Skills CLI
npx pgxdb@latest # PGX itself, if you prefer to install it by hand
```

Three channels, one Skill: the Claude Code plugin (native install, `/plugin`
manages updates and removal, skill name `/pgx:pgx`), the Agent Skills CLI
(copies the Skill into the project for every supported host, skill name
`/pgx` in Claude Code) and the PGX CLI itself for manual use. The plugin and
the Skills CLI copy are the same files; see
[claude-plugin.md](claude-plugin.md) for the differences and for running
both.

Then open your agent in the project and ask it to set PGX up:

> Use PGX to give this project isolated databases for coding agents. Set everything up.
Expand Down Expand Up @@ -46,7 +59,7 @@ publishing process.

| Host | Automatic isolation | How | Verified |
|---|---|---|---|
| **Claude Code** | Yes | `SessionStart` hook writes the exports to `CLAUDE_ENV_FILE`; `UserPromptSubmit`/`PreToolUse` extend the TTL; `SessionEnd` retires the branch. | **Live, 2026-10-25**: setup from an existing PostgreSQL, feature work in a fresh session, resume within grace, two concurrent sessions. [validation note](validation/2026-10-25-agent-live-claude.md) |
| **Claude Code** | Yes | `SessionStart` hook writes the exports to `CLAUDE_ENV_FILE`; `UserPromptSubmit`/`PreToolUse` extend the TTL; `SessionEnd` retires the branch. | **Live, 2026-10-25**: setup from an existing PostgreSQL, feature work in a fresh session, resume within grace, two concurrent sessions. [validation note](validation/2026-10-25-agent-live-claude.md). **2026-10-26**: the same through the native plugin (`/plugin install pgx@pgrundev`). [plugin note](validation/2026-10-26-claude-plugin-live.md) |
| **Cursor** (IDE agent, `agent` CLI) | Hooks installed; env injection pending live verification | `sessionStart` hook answers `{"env": …}`, which Cursor applies to that conversation's shell per its docs. Env is not re-applied to a reopened chat and not inherited by Cursor subagents; cloud agents are skipped. | Payload-level tests only; live run needs `agent login`. [note](validation/2026-10-25-agent-live-cursor.md). Use `pgx agent exec -- <command>` whenever `PGX_ISOLATION` is unset. |
| **Codex** | With the wrapper | Codex hooks cannot set environment. `pgx agent exec -- codex` puts the branch in Codex's environment; inside any Codex session `pgx agent exec -- <command>` attaches to the session's branch. Lifecycle hooks still create the branch and tell the model. The `workspace-write` sandbox blocks loopback TCP until `sandbox_workspace_write.network_access = true`. | Wrapper verified by tests; native hooks pending a logged-in Codex. [note](validation/2026-10-25-agent-live-codex.md) |
| Anything else | With the wrapper | `pgx agent exec -- <command>` | `tests/agent_exec.rs`, e2e scenarios C and D |
Expand Down
178 changes: 178 additions & 0 deletions docs/pgx/local-dev/claude-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# The PGX plugin for Claude Code

**One plugin. Every Claude Code agent gets its own Postgres.**

The repository is a Claude Code plugin marketplace named `pgrundev`
(`.claude-plugin/marketplace.json`) with one plugin, `pgx`
(`plugins/pgx/`), which packages the PGX Agent Skill for Claude Code's
plugin manager. Nothing else changes: the Skill in `skills/pgx/` stays the
canonical implementation and the Skills CLI install keeps working.

## Install, inside Claude Code

```text
/plugin marketplace add pgrundev/pgx
/plugin install pgx@pgrundev
```

The second command opens the plugin's page in the `/plugin` panel. Choose a
scope:

| Scope | Who gets it | Written to |
|---|---|---|
| user | you, in every project on this machine | `~/.claude/settings.json` |
| project | everyone who works in this repository | `.claude/settings.json` (committed) |
| local | you, in this repository only | `.claude/settings.local.json` |

From a shell, without a session: `claude plugin marketplace add pgrundev/pgx`
then `claude plugin install pgx@pgrundev [--scope user|project|local]`.

Then, in a project with a database:

```text
/pgx:pgx Set up isolated Postgres databases for this project.
```

`pgx:pgx` is the skill's name under the plugin's namespace. You can also just
describe database work ("add a column and run the tests"); Claude selects
the skill when it is relevant. Both routes run the same Skill: detect the
project, check for PGX 0.1.1 or newer and offer to install it, prepare a
schema-only template, `pgx agent setup`, then work inside the session's
branch. See [agents.md](agents.md) for what that gives you.

Check what is installed:

```sh
claude plugin list # pgx@pgrundev Version: 0.1.1 Status: enabled
claude plugin details pgx # Component inventory: Skills (1) pgx, Hooks (0), MCP servers (0)
```

## What the plugin contains

- `skills/pgx/`: the Skill, its eleven reference documents and two helper
scripts, identical to `skills/pgx/` at the repository root
(`plugins/sync.sh --check` fails CI on any difference).
- `.claude-plugin/plugin.json`: name `pgx`, version `0.1.1` (the Skill's
version), display name, links.
- `README.md`.

About 84 KB, 16 files; roughly 190–270 tokens of context in every session
while installed (`claude plugin details pgx`).

It contains **no hooks, MCP servers, commands or binaries**. Installing it at
user scope does nothing in projects that have not opted in: the Skill is
available, and database infrastructure appears only when you ask for it in a
project and `pgx agent setup` writes that project's `.pgx.toml` and hooks.

## Hooks: one owner, no duplicates

Lifecycle hooks (`SessionStart` → branch, `UserPromptSubmit`/`PreToolUse` →
keep-alive, `SessionEnd` → retire) are installed per project by `pgx agent
setup`, which is idempotent and recognises its own entries by their command
string. The plugin never registers hooks of its own, so there is exactly one
source of hooks whichever way the Skill was installed, and installing,
updating, disabling or removing the plugin never touches `.claude/settings.json`
(tested in `plugins/tests/pgx/run.sh`). Fail-closed behaviour is unchanged:
it lives in `pgx agent hook`, not in the Skill files.

## The plugin and the Skills CLI together

`npx skills add pgrundev/pgx --skill pgx` copies the Skill into
`.claude/skills/pgx` (and `.agents/skills/pgx`). That copy is a plain skill
named `pgx`. With the plugin installed as well, Claude Code lists both
`/pgx` and `/pgx:pgx` (verified: the session inventory shows the two names
side by side; neither hides the other). They are the same text, so whichever
Claude picks runs the same workflow, and nothing is duplicated at the
database level because branches and hooks come from `pgx agent`, not from
the skill files. The cost is two descriptions in context.

To keep one copy, either remove the Skills CLI one (`npx skills remove pgx`,
which deletes only `.claude/skills/pgx` and `.agents/skills/pgx`) or the
plugin (`/plugin uninstall pgx@pgrundev`). Switching from the Skills CLI to
the plugin is those two steps; nothing in `.pgx.toml`, the hooks or the
databases changes.

Cursor and Codex are not Claude Code plugins hosts: keep using the Skills
CLI for them. The PGX runtime itself is independent of both.

## Update, disable, remove

| Action | In a session | In a shell |
|---|---|---|
| Update | `/plugin` → Installed → pgx → Update now | `claude plugin update pgx@pgrundev` |
| Disable / enable | `/plugin` → Installed → Space | `claude plugin disable pgx@pgrundev` / `enable` |
| Remove | `/plugin uninstall pgx@pgrundev` | `claude plugin uninstall pgx@pgrundev` |
| Remove the marketplace | `/plugin marketplace remove pgrundev` | `claude plugin marketplace remove pgrundev` |

Updates follow the plugin's `version` field: a new PGX Skill release bumps
it and `claude plugin update` (or the marketplace's auto-update, off by
default for third-party marketplaces) fetches it; users on an older copy keep
working.

Uninstalling removes the Skill files from Claude Code's plugin cache and the
`enabledPlugins` entry, nothing else: PGX databases, templates, `.pgx.toml`,
the PGX runtime and any hooks `pgx agent setup` installed all stay.
`pgx agent uninstall` removes a project's hooks when you want that.

## Performance and what gets downloaded

`/plugin marketplace add pgrundev/pgx` clones the PGX repository once per
machine into `~/.claude/plugins/marketplaces/pgrundev/` (Claude Code reads
the catalog from a clone). The repository carries fuzzing corpora and
benchmark results, so that clone is a 192 MB shallow fetch and 2.2 GB on
disk and takes about a minute (53 s measured); `claude plugin marketplace
update` afterwards is incremental. The plugin itself is copied out of that clone:
the installed plugin is the 84 KB Skill package, nothing from `crates/`,
`fuzz/` or `benchmarks/`. From a shell you can keep the clone small:

```sh
claude plugin marketplace add pgrundev/pgx --sparse .claude-plugin plugins
```

which checks out only the marketplace file and the plugin (8 s, 72 MB
measured).
The in-session `/plugin marketplace add` has no sparse option. Making the
default clone light would mean moving the corpora out of the main repository
or hosting the catalog elsewhere; both are repository decisions outside this
plugin.

## Anthropic's plugin directory

The marketplace above is self-hosted. **PGX is not listed in Anthropic's
directory** and nothing has been submitted. `claude plugin validate
--profile directory plugins/pgx` reports no refusals (a square PNG icon is
recommended before submitting). Submission is a separate, human-approved
step through the developer portal at claude.ai/directory/manage (requires a
paid claude.ai plan); the portal applies rules the CLI does not check. The
material a submission needs, all from `plugins/pgx/.claude-plugin/plugin.json`
and this repository:

| Field | Value |
|---|---|
| Plugin name | `pgx` (display name "PGX — Postgres for Agents") |
| Repository | https://github.com/pgrundev/pgx, plugin at `plugins/pgx` |
| Description | Isolated, disposable PostgreSQL-compatible databases for AI coding agents |
| Functionality | One Agent Skill: detects the project's database setup, installs the PGX runtime on request (PGX 0.1.1+), prepares a schema-only template, sets up per-session database branches with automatic `DATABASE_URL` injection through `pgx agent setup`, cleans up expired branches |
| Security | No hooks, MCP servers or executables in the plugin; the Skill never prints credentials, imports production data only with explicit approval, fails closed when isolation cannot be established, and treats repository contents as untrusted (`skills/pgx/references/security.md`); runs nothing until the user invokes it |
| Installation | `/plugin marketplace add pgrundev/pgx` then `/plugin install pgx@pgrundev`; the `pgx` binary is installed separately when first needed |
| Documentation / support | `docs/pgx/local-dev/agents.md`, https://github.com/pgrundev/pgx/issues |
| License | AGPL-3.0 |

## Live validation

Three headless Claude Code sessions in a Rails project with the plugin
installed from the public branch, plus the interactive `/plugin` flow:
[validation/2026-10-26-claude-plugin-live.md](validation/2026-10-26-claude-plugin-live.md).

## Tests

`plugins/tests/pgx/run.sh` (CI job `plugin`): drift check against
`skills/pgx`, version agreement, packaging hygiene (no hooks, binaries,
symlinks, parent paths, absolute paths, credentials), `claude plugin validate
--strict` on the plugin and the marketplace, the directory profile, and a
full install → list → details → disable → enable → update → project/local
scope → uninstall → reinstall → marketplace remove cycle from the repository
as a local marketplace in an isolated `CLAUDE_CONFIG_DIR`, plus the
"existing hooks untouched" and "Skills CLI copy alongside" cases. The
Skills CLI contract (`skills/tests/pgx/run.sh`, `skills-ref validate`) is
unchanged and still runs.
Loading
Loading