Skip to content

Latest commit

 

History

History
251 lines (173 loc) · 9.02 KB

File metadata and controls

251 lines (173 loc) · 9.02 KB

Contributing to Plexus

Getting Started

git clone https://github.com/<owner>/plexus.git
cd plexus
bun install

Running bun install automatically installs git hooks via Lefthook (the prepare script runs lefthook install). No extra setup is needed.

Database Schema Changes

Plexus uses Drizzle ORM with dual-dialect support (SQLite and PostgreSQL). Schema definitions live in:

  • packages/backend/drizzle/schema/sqlite/ -- SQLite table definitions
  • packages/backend/drizzle/schema/postgres/ -- PostgreSQL table definitions

How to make schema changes

  1. Edit the schema .ts files in the appropriate dialect directories
  2. If adding a new table, update the index exports in packages/backend/drizzle/schema/index.ts
  3. (Optional) Validate locally by running bun run generate-migrations from packages/backend/ -- this confirms your schema produces valid migration SQL. The name is auto-derived from your branch; you can also specify --name <descriptive-name> explicitly.
  4. Do NOT commit migration artifacts (.sql files, meta/_journal.json, snapshot files). Only commit the schema .ts files.
  5. Open your PR. Migrations are auto-generated by CI after your PR merges to main.

Why this policy?

Drizzle migrations use sequential numbering. When multiple PRs include migrations, they collide on merge (e.g., two PRs both generate migration 0030). By keeping migration generation as a post-merge CI step, conflicts are impossible.

What if the pre-commit hook blocks my commit?

The pre-commit hook prevents accidentally committing migration files. If it fires:

# Remove migration files from your staged changes
git reset HEAD -- packages/backend/drizzle/migrations/ packages/backend/drizzle/migrations_pg/

Then commit again with only your schema .ts files.

Skipping hooks

The hooks are skipped automatically when CI=true (GitHub Actions). To skip locally in exceptional circumstances:

LEFTHOOK=0 git commit -m "..."

Drizzle Config Files

The project uses separate Drizzle ORM config files for each database dialect:

  • drizzle.config.sqlite.ts -- SQLite configuration
  • drizzle.config.postgres.ts -- PostgreSQL configuration

When running Drizzle Kit commands, specify the appropriate config file with --config.

Pi Assistant & PR Agent Review

Plexus uses Pi Assistant and PR Agent for automated coding assistance and code reviews:

  • Pi Assistant (.github/workflows/pi-assistant-issue.yml and .github/workflows/pi-assistant-pr.yml): Triggered by commenting /pi on an issue or PR. It uses the mcowger/pi-action action to run an AI-agent-driven coding session directly in the repository context to address requested changes. System prompts live in .github/prompts/pi-assistant-issue.md and .github/prompts/pi-assistant-pr.md.
  • PR Agent Review (.github/workflows/pr-agent-review.yml): Triggered automatically when non-draft pull requests are opened/reopened/ready for review, or when comments are made. It performs thorough automated code reviews using the the-pr-agent/pr-agent action, configured via .pr_agent.toml.

Optional: advisory PR-Agent pre-push review (local)

A pre-push Lefthook hook can run PR-Agent locally on the diff you are about to push, in plain-diff mode — it pipes a unified diff to PR-Agent's stdin, so it needs no GitHub credentials and no PR URL. The review is printed to your terminal and is purely advisory: the hook always exits 0 and can never block a push. If PR-Agent isn't installed, its config is missing, or the LLM call fails, you just get a warning and the push proceeds.

One-time setup (idempotent — safe to re-run), using mise-managed Python:

mise install             # installs the pinned Python 3.12 (and other tools)
mise run pr-agent:setup  # creates .venv and pip-installs a pinned pr-agent

Equivalent explicit commands, if you prefer to do it by hand:

mise use python
mise exec -- python -m venv .venv
mise exec -- .venv/bin/python -m pip install pr-agent

Configuration is read from the repo's .pr_agent.toml plus environment variables — supply values in your shell profile or a local, git-ignored file. Never commit keys or secrets.

Variable Purpose
OPENAI__KEY API key for your LLM provider (not needed when CONFIG__MODEL points at a local model, e.g. Ollama)
OPENAI__API_BASE Optional endpoint override (proxy, Azure, or a local server)
CONFIG__MODEL Optional model override (defaults to the PR-Agent built-in default)

Plain-diff mode works fully offline from GitHub, but still requires an LLM: either a provider key (OPENAI__KEY) or a locally hosted model (CONFIG__MODEL + OPENAI__API_BASE, e.g. an OpenAI-compatible Ollama server).

To run a review manually (no push needed), use the package script — it diffs origin/HEAD...HEAD by default, or any base you pass:

bun run review                # review origin/HEAD...HEAD
bun run review origin/main    # review a custom base

Or invoke PR-Agent directly on any diff:

git diff origin/main...HEAD | .venv/bin/python -m pr_agent.cli --stdin review

Code Style

All code must be formatted with Biome before committing:

bun run format

Running Tests

From the repo root:

bun run test

Or from the backend package:

cd packages/backend
bun run test

Note: bun test is intentionally blocked both at repo root and in packages/backend. Use bun run test instead.

The pre-commit hook runs backend tests automatically.

Development

Starting the dev server

bun run dev

This starts the backend (with file watching) and the frontend builder in parallel.

The port is derived automatically from the worktree directory name, so two worktrees can run simultaneously without collision. The port and database are printed at startup:

Starting Plexus Dev Stack...
  PORT:         14641
  DATABASE_URL: sqlite:///tmp/plexus-browsertesting.db
  ADMIN_KEY:    password

Override any of these with environment variables:

PORT=4000 ADMIN_KEY=mysecret bun run dev

PGlite mode (no external database required)

To run against an in-process PGlite database instead of SQLite — useful when testing Postgres-specific behaviour without running a real server:

bun run dev:pglite

The startup output shows the data directory instead of a database URL:

Starting Plexus Dev Stack...
  PORT:         14641
  DB Driver:    PGlite
  DB Data Dir:  /tmp/plexus-browsertesting.pglite
  ADMIN_KEY:    password

The data directory persists across restarts (same worktree isolation as SQLite). Override it with PLEXUS_PGLITE_DATA_DIR=/path/to/dir bun run dev:pglite.

Seeding baseline data

After starting the dev server, seed it with a realistic baseline configuration (providers, model aliases, quota definitions, and API keys) that exercises the full feature set without requiring any real external credentials:

bun run populate-dev

This is idempotent — safe to re-run at any time. It uses PUT throughout, so existing resources are replaced rather than duplicated.

What gets seeded

Category Count Notes
Providers 11 Frontier cloud providers (Kilocode, Wisgate, Neuralwatt, OpenRouter, Google, OpenAI, Anthropic, CC, CC-Sigma, OpenLimits, Ozore)
Quotas 2 Daily, weekly budgets and limits
Model aliases 19 Frontier model architectures (gpt-5.x, claude-4.5/5, gemini-3.5, deepseek-v4) for chat, embeddings, speech, transcriptions
API keys 4 Default, OWUI, GithubKey, GHAKey

All provider URLs are mapped to their real production API gateways, but with safe, redacted mock keys by default. No real secrets are checked into the codebase.

Adding your own data

Create scripts/user-populate.json (git-ignored — see scripts/user-populate.example.json for the format). Anything in that file is merged over the defaults when you run bun run populate-dev, so you can add real provider keys or personal aliases without touching committed files and without risk of accidentally leaking secrets.

Environment variables

Variable Default Purpose
PLEXUS_URL http://localhost Base URL of the target instance
PLEXUS_PORT derived from cwd Port (matches bun run dev automatically)
PLEXUS_ADMIN_KEY password Admin key

Resetting to a clean state

To wipe the database and restart the backend in one step:

bun run clear-dev

This deletes the SQLite file from /tmp and sends SIGHUP to the running dev server, which gracefully shuts down the backend and immediately relaunches it against the empty database. The frontend is unaffected. The whole cycle takes about two seconds.

After clearing, re-run bun run populate-dev to restore the baseline config.

Note: clear-dev relies on a PID file written by bun run dev to /tmp/plexus-<worktree>.pid. If the server is not running, it will delete the database file and exit cleanly without error.