Engineering

Paxel Integration (P5)#

Co-Vibe runs the official YC Paxel tool — the public ycombinator/paxel Docker image from paxel.ycombinator.com — never a clone. Paxel analyzes a developer's local Claude Code, Codex, and Cursor sessions and returns a builder profile (scores, archetypes, decision patterns).

Because the transcripts live on the developer's machine, the local companion executes Paxel locally; the Co-Vibe server only records the request and the resulting report reference. No transcript or source content passes through the Co-Vibe server or the browser.

Flow#

  1. A developer opens their own profile (Performance → their row) and clicks Run Paxel (optionally choosing All repos and a project name). This POSTs { action: "request" } to /api/paxel, creating a paxel_runs row with status requested.

  2. On the developer's machine, covibe-local paxel — Paxel is strictly user-triggered; the background watch loop never claims or runs it — authenticates with the MCP token and POSTs { operation: "claim" } to /api/paxel/runner. The server atomically moves the oldest pending run to running and returns its options, so a UI-requested run is picked up the next time the developer runs covibe-local paxel. Claiming with create: true (ad-hoc companion run) while the developer already has a requested/running run is rejected with a 409 so a developer never has more than one active run.

  3. The companion verifies Docker is running, then executes the official image:

    bash
    docker run --rm \
      -v ~/.claude:/claude:ro -v ~/.cursor:/cursor:ro -v ~/.codex:/codex:ro \
      -v "$(pwd)":/workspace \
      ycombinator/paxel [--project NAME] [--since DATE] [--no-repo] [--no-sentry]

    For an all-repo run the working-tree mount is omitted and --no-repo is passed. The worktree mount is only added for a single-repo run.

  4. The companion parses the official output for the report URL/token and POSTs { operation: "complete", status, report_url, report_token } back to /api/paxel/runner. The run becomes completed (or failed — Docker exit, Docker unavailable, or timeout all report a useful error).

  5. The profile polls /api/paxel while a run is active — at the pollIntervalMs cadence the overview response supplies — and shows the report link + token when it lands.

Strictly user-triggered (no watch integration)#

The machine-level covibe-local watch loop never claims or executes Paxel runs — by design, no background process touches local agent transcripts unattended. Clicking Run Paxel in the UI queues a requested run; it executes only when the developer runs covibe-local paxel on their machine, which claims the pending run before creating an ad-hoc one. The watch loop logs Paxel runs are user-triggered (covibe-local paxel) at startup.

Timeouts and stale runs#

  • Execution timeout (companion): the Docker process is killed after 30 minutes by default; override with COVIBE_PAXEL_TIMEOUT_MS or --timeout-ms. A timed-out run is completed failed with a timeout error.
  • Stale run cleanup (server): a run stuck in running whose started_at is older than 2 hours (override with COVIBE_PAXEL_STALE_MS) is marked failed with error abandoned by companion and a paxel_run_abandoned work event. The cleanup runs lazily during the /api/paxel overview GET and the runner claim — no cron needed.

Running it#

bash
# one-off, current repo (creates + runs immediately):
npm exec -- covibe-local paxel --base-url http://localhost:3000

# all repos, named project, skip Sentry:
npm exec -- covibe-local paxel --all-repos --project acme --no-sentry

# preview the exact docker command without executing (no token, no server contact):
npm exec -- covibe-local paxel --dry-run

# a UI-requested run is claimed by the same command — run it after clicking
# Run Paxel in the console (the background watch loop never runs Paxel):
npm exec -- covibe-local paxel

Keep COVIBE_MCP_TOKEN exported (same token used for MCP) for real runs; a --dry-run works without it. The companion never prints the raw token, and error strings are clipped to the last 1000 characters of stderr with cv_ tokens masked.

Visibility & enablement#

  • Capability flag paxel_enabled (see .env.example COVIBE_PAXEL_ENABLED): default on for local/self-hosted, off for the central hosted origin where the server cannot reach a developer's Docker. A tenant admin can toggle it from Settings ({ action: "set_enabled" }).
  • Per-run sharing tenant_visible: a completed report is private to the developer by default; the owner can mark it team-visible from the profile ({ action: "set_visibility" }). Team-visible reports appear read-only on that developer's Performance profile for teammates in the same workspace.
  • Image/binary overrides COVIBE_PAXEL_IMAGE / COVIBE_PAXEL_DOCKER support podman, OrbStack, and Colima, and pin a specific image for CI.

Data model#

paxel_runs is workspace-scoped with Postgres RLS plus repository workspace filters and stores: run_type (repo|all-repo), project, since, no_repo, no_sentry, status (requested|running|completed|failed|cancelled), tenant_visible, requested_by (ui|companion), report_url, report_token, output_reference, error, and request/start/complete timestamps. No transcript or diff content is ever stored.

Code map#

  • Schema: src/server/db/schema-paxel-statements.ts
  • Repository: src/server/repositories/paxel-runs.ts
  • Feature flag: src/server/paxel/feature-flag.ts
  • UI actions / overview: src/server/paxel/actions.tssrc/app/api/paxel/route.ts
  • Companion runner (token auth): src/server/paxel/runner.tssrc/app/api/paxel/runner/route.ts
  • Stale cleanup: src/server/paxel/stale.ts
  • Companion command: scripts/local-runtime/paxel-run.ts (+ paxel-deps.ts, paxel-command.ts), wired in scripts/local-companion.ts
  • Unwired watch claimer (kept for reference, no callers): scripts/local-runtime/paxel-watch.ts
  • UI panel: src/features/console/views/redesign/profile-paxel.tsx (admin toggle in redesign/admin-controls.tsx)
View as .md