Skip to main content

Pre-push risk check + cloud-connected CLI for LocAgent. Maps your local diff to its dependency blast radius and checks it against your team's incident memory.

Project description

perla

LocAgent's developer CLI: triage incidents and catch risky changes — from your terminal.

perla brings two LocAgent workflows into your shell:

  1. Triage an error / stack trace / failed CI run from the command line — the agent reads your code, finds the root cause, and (when you want) opens a fix PR. No dashboard required.
  2. Pre-push risk check — before you push, perla preflight maps your local diff to its dependency blast radius and checks it against your team's incident history. Changes that touch the exact function that broke production last quarter get flagged with a real reason.

Both run against your LocAgent workspace and reuse the memory you've built up there.

Two flows

Triage from the terminal

$ perla recall "TypeError: cannot read 'id' of undefined in checkout"
  Found 2 similar past incident(s):
    • [91%] Null deref in checkout.finalize — unguarded session lookup
        files: services/checkout.py
        id: cmp_inv618

$ perla investigate "NPE in checkout.finalize at deploy 4f7c2" --follow
  ⠋ Investigating omnia-v/omnia…
  ✓ Root cause: services/checkout.py:142 — unguarded session lookup
    Causes:
      [root]        services/checkout.py:finalize
      [contributing] services/auth.py:resolve_session
  → https://app.locagent.dev/.../investigations/cmp_inv719

$ perla fix cmp_inv719
  Generating fix… (1-3 minutes)
  ✓ Fix PR opened: https://github.com/your-org/your-repo/pull/718

investigate / recall / show / ls / fix — the whole triage loop, from terminal to merged fix.

Pre-push risk check

$ perla preflight

  Changed entities & blast radius:
    • services/checkout.py:finalize  (function) ← 12 dependents  ⚠ high fan-in

  Memory: checked (47 past incidents scanned)
    ⚠ Null deref in checkout.finalize — unguarded session lookup [cmp_inv618]

  Verdict: ⚠ RISKY  (cloud)
    - Removes the None-guard that was added in incident #618
    - 12 entities depend on this function (payment, mobile, admin)
    → Re-add the session guard before pushing.

Exit code 1 on RISKY — drop it in a pre-push git hook or a CI step and it gates the push.


Install

uv tool install perla         # recommended
pipx install perla            # or pipx
pip install perla             # or pip

Requires Python 3.12+. The CLI works fully offline for local code intelligence and only talks to the cloud when you ask it to (see verdict modes below).

First run, in 60 seconds

# 1. Offline / no setup — works in any git repo
cd ~/some-git-repo
# (make a code change)
perla preflight --no-memory --verdict-mode local

# 2. Connect to your workspace for memory-grounded verdicts
perla login                   # paste a workspace API key from the dashboard
perla preflight               # now uses the cloud verdict + incident memory

The 13 commands

Triage — agent reads your code, finds the cause, opens the PR

perla recall "<error>" "Have we seen this before?" — semantic search across your workspace's incident memory.
perla investigate "<text>" [--follow] Dispatch a full triage. --follow polls to completion and prints the briefing.
perla show <id> Read an investigation + its briefing (root cause, contributors, files).
perla ls List recent investigations.
perla fix <id> Open a fix PR from a triaged finding (patch-on-demand).

Pre-push risk check

perla preflight Diff → blast radius → memory lookup → verdict. Exit 1 on risky for git-hook / CI use.

Local code intelligence — works offline, no login

perla build [path] Build a dependency graph of a repo (tree-sitter → NetworkX).
perla search <query> BM25 + fuzzy code search over the graph.
perla explore <entity> Traverse the graph: callers, callees, importers.
perla blame <entity> Git temporal forensics — who last touched it, when.

Connection

perla login Paste a workspace API key (loc_...); stored 0600 at ~/.config/perla/credentials.json.
perla whoami Show the connected workspace + repos.
perla logout Remove stored credentials.

Three verdict modes

perla preflight --verdict-mode <mode> — the customer chooses the trust posture:

Mode Where the diff goes Use when
cloud (default) The LocAgent worker. Same trust model as auto-PR. Best verdict quality; you're OK sending diffs to the workspace.
byok Your own model provider (OpenAI / Anthropic / Ollama / any OpenAI-compatible). You want LLM reasoning but no third party seeing your code.
local Nowhere. Rule-based blast-radius reasoning, no model. Offline, CI without keys, the deterministic floor.

Any model/connection failure degrades to the local floor automatically — perla preflight never hard-fails.

Use in CI

# .github/workflows/preflight.yml
- run: pip install perla
- run: perla preflight --json     # exit 1 on risky → gates the job
  env:
    PERLA_API_KEY: ${{ secrets.PERLA_API_KEY }}

Or pre-push hook:

# .git/hooks/pre-push
#!/bin/sh
perla preflight || exit $?

Environment variables

Var When What
PERLA_API_KEY CI / scripts Workspace API key; overrides perla login
PERLA_BASE_URL Self-hosted dashboard LocAgent dashboard base URL
PERLA_LLM_KEY byok mode Your own model provider key
PERLA_LLM_BASE_URL byok non-OpenAI OpenAI-compatible base (Anthropic, Ollama, etc.)
PERLA_LLM_MODEL byok Defaults to gpt-4o-mini
PERLA_REPOSITORY_ID rare Override the auto-resolved workspace repo
PERLA_CONFIG_DIR rare Credentials file location (defaults to XDG)

Privacy posture

  • Local mode: diff never leaves the machine.
  • BYO mode: diff goes to your model provider; LocAgent's cloud only ever sees file/entity names (for the memory lookup).
  • Cloud mode: diff goes to your LocAgent workspace runtime — the same place auto-PR sends already-pushed code.

The cloud memory lookup (preflight-memory, recall) always sends only paths and entity names — never source.

How it works

                                    ┌─────────────────────┐
git diff (working tree, uncommitted)│  perla (local)      │
        ↓                           │                     │
changed files + line ranges         │  tree-sitter graph  │
        ↓                           │  ────────────────►  │
graph node spans → changed entities │  reverse-BFS deps   │
        ↓                           └──────────┬──────────┘
blast radius (who depends on them)             │
        ↓                                       │
        │  file/entity names only ─────────────►│ LocAgent workspace
        │                                       │  (incident memory)
        │  ◄───── prior incidents ──────────────│
        ↓                                       │
verdict (cloud / byok / local) ─────────────────┘

perla ships only the local graph engine (dependency_graph, tree-sitter) plus a thin HTTP client. No FastAPI service, no agent loop, no LLM bundled — cloud mode dispatches to your LocAgent worker, byok calls your provider directly.

Status

Beta. The 4 core modules (preflight, verdict, workspace, auth) ship at 100% test coverage. The full surface is exercised end-to-end against a real workspace in our internal CI. Breaking changes possible before 1.0; see CHANGELOG.md.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

perla-0.1.17.tar.gz (273.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

perla-0.1.17-py3-none-any.whl (209.1 kB view details)

Uploaded Python 3

File details

Details for the file perla-0.1.17.tar.gz.

File metadata

  • Download URL: perla-0.1.17.tar.gz
  • Upload date:
  • Size: 273.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for perla-0.1.17.tar.gz
Algorithm Hash digest
SHA256 95e0b1afacf912754f5c963d8e9158a74d893eb1a4806800456b56e4a68686e2
MD5 61328949bea4c51966172bc51a563f1f
BLAKE2b-256 bef483f4b914b32ef69bce7a58c2ac0f630ff00619cfc2392a5d27745869305c

See more details on using hashes here.

File details

Details for the file perla-0.1.17-py3-none-any.whl.

File metadata

  • Download URL: perla-0.1.17-py3-none-any.whl
  • Upload date:
  • Size: 209.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for perla-0.1.17-py3-none-any.whl
Algorithm Hash digest
SHA256 358c83a5c451ce4aee9d0e7c5222af5462bf5fc11b760dd773b7e420d4a27d25
MD5 aed1bb8fdcc7a677015a6ae63f82e70e
BLAKE2b-256 a257f23a830d0e9cb98d77b6307f9945d735561f0661c29211c3da0c70d23edd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page