Skip to content

Latest commit

 

History

History
160 lines (113 loc) · 4.93 KB

File metadata and controls

160 lines (113 loc) · 4.93 KB

Development

Prerequisites

  • Python 3.11+
  • uv
  • pnpm
  • Docker and Docker Compose

Repository Structure

Directory Component Stack
shared Shared models, scoring, schema Python, Pydantic
plugins/acq/server MCP server (plugin) Python, FastMCP
team-api Team Q&A API Python, FastAPI
team-ui Review dashboard TypeScript, SvelteKit, Tailwind

Initial Setup

git clone https://github.com/seanmeyer/acq.git
cd acq
make setup

Running Locally

The quickest way to run everything is with Docker Compose.

Export the required secret first:

export ACQ_JWT_SECRET=dev-secret

Start all services (runs in the foreground):

make compose-up

In a separate terminal, create a user:

make seed-users USER=demo PASS=demo123

The team API is available at http://localhost:8742. The review UI is available at http://localhost:3000.

For isolated component testing outside Docker, use make dev-api (team API) and make dev-ui (dashboard).

Agent Configuration

Production (team API)

Run make setup — it installs dependencies and runs scripts/setup-agent.py which authenticates via GitHub device flow and writes credentials to ~/.claude/settings.json.

Local dev

To point your agent at a local team API instance:

{
  "env": {
    "ACQ_TEAM_ADDR": "http://localhost:8742",
    "ACQ_TEAM_API_KEY": "default-key"
  }
}

Deploying to Howler

The team API and review UI are bundled into a single Docker image and deployed to Howler (service ID 222). The Dockerfile uses a multi-stage build: Node builds the SvelteKit UI, then the Python image copies in the static assets and serves them via FastAPI.

Secrets

These are configured via the Howler UI or API at /api/services/222/secrets/:

Secret Purpose
ACQ_JWT_SECRET Signs session JWTs
ACQ_API_KEYS JSON map of static API key → agent name (dev/test fallback only)
ORGSTORE_CLUSTER DogPark cluster name (dogpark) — enables Postgres
DB_NAME DogPark database name (dev_db_acq)
DB_USER DogPark database role (dev_db_acq)
DB_HOST pg-proxy host (auto-derived if not set)
GITHUB_CLIENT_ID GitHub OAuth app client ID
GITHUB_CLIENT_SECRET GitHub OAuth app client secret

DogPark Schema Migrations

The team API uses a DogPark developer database (dev_db_acq on the dogpark cluster). DogPark's default roles lack CREATE permission, so DDL changes must be run via the admin bypass role in the toolbox. Do not use orgstore toolbox psql — it connects as the default role which cannot create tables.

To run DDL (from a machine with kubectl access — not workspaces):

DEV_DB=dev_db_acq

kubectl exec \
  --context gizmo.us1.staging.dog \
  --namespace orgstore-dogpark \
  -it \
  deployment/orgstore-dogpark-toolbox -- \
  pg-wrap -o dogpark -b admin -D $DEV_DB psql

The -b admin flag is critical — it bypasses the default role and connects with CREATE permission on the dogpark schema. You can then run any DDL:

CREATE TABLE IF NOT EXISTS dogpark.my_new_table (...);

Note: DogPark is not compatible with PG Schema Manager (PGSM/Alembic). DDL changes are manual via the toolbox. See the DogPark Confluence page for details.

Deploy

Build a tarball with the Dockerfile at root and deploy:

tmpdir=$(mktemp -d)
cp team-api/Dockerfile "$tmpdir/Dockerfile"
cp -r shared team-api team-ui "$tmpdir/"
tar czf /tmp/acq-deploy.tar.gz -C "$tmpdir" .
curl -X POST "https://howler.us1.staging.dog/api/services/222/builds/" \
  -F "build-context.tgz=@/tmp/acq-deploy.tar.gz"

The response streams build and deploy logs. The field name must be build-context.tgz — any other name returns a silent 500.

The service is live at https://acq-team-api.us1.staging.dog/ once the deploy finishes. Fabric destinations and routing domains are already configured.

Authentication

Production uses GitHub OAuth — users click "Sign in with GitHub" and their GitHub username becomes their identity. The GitHub OAuth app is registered at github.com/settings/applications with callback URL https://acq-team-api.us1.staging.dog/auth/callback.

Local dev (docker-compose) still uses username/password via make seed-users.

Docker Compose

Command Purpose
make compose-up Build and start services
make compose-down Stop services
make compose-reset Stop services and wipe database
make seed-users USER=demo PASS=demo123 Create a user

Validation

Command Purpose
make lint Format and lint all Python components
make test Run tests across shared, team-api, and MCP server