Skip to content

Latest commit

 

History

History
210 lines (143 loc) · 7.07 KB

File metadata and controls

210 lines (143 loc) · 7.07 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 Prompt

The system prompt for the /pi AI agent lives at .github/prompts/pi-assistant.md. Edit that file directly — do not put prompt text inside the workflow YAML.

The file supports {{dot.notation.path}} placeholders that are substituted at runtime:

  • {{context.payload.comment.body}} — the triggering comment's text
  • {{context.payload.issue.number}} — issue/PR number
  • {{context.actor}} — the GitHub actor who triggered the run
  • {{env.GITHUB_SHA}} — any GITHUB_* / RUNNER_* runner environment variable
  • {{env.INITIAL_COMMENT_ID}} — a value passed explicitly via the step's env: block

Anything reachable from the @actions/github context object is available under context.* without any extra wiring. Values that come from previous step outputs (like INITIAL_COMMENT_ID) must be added to the env: block on the Run Pi agent step in .github/workflows/pi-assistant.yml.

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 7 Local (Ollama, LM Studio, llama.cpp) + mock cloud (OpenAI, Anthropic, Gemini, OpenRouter)
Quotas 7 Rolling, daily, weekly windows; requests and token limits
Model aliases 16 chat, embeddings, speech, transcriptions, image types; multi-target failover aliases
API keys 14 Unrestricted, quota-enforced, provider-restricted, model-restricted

All provider URLs point at localhost — no real API keys are needed by default.

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.