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.5.tar.gz (180.9 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.5-py3-none-any.whl (158.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: perla-0.1.5.tar.gz
  • Upload date:
  • Size: 180.9 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.5.tar.gz
Algorithm Hash digest
SHA256 c48232f3b87c752f05b054ee59afe9cd912a1f8f4ead9d156da55ab87ca7c6d4
MD5 e0c845d88db459efd2667d5cfedf9705
BLAKE2b-256 55b5efb5b67b8ba0b807e2639679c23919e8f7da87845863178f2d1d63f9c120

See more details on using hashes here.

File details

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

File metadata

  • Download URL: perla-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 158.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.5-py3-none-any.whl
Algorithm Hash digest
SHA256 8096813ef4b98fb4896b67f7a71e7470c87bd311b5996b137d67e765e8fe983e
MD5 c84b1ba5e4010404f7c8e796c468d71a
BLAKE2b-256 9d8304deedbad8bdb8561685b5e46d76e4198826529acb426140ffccd746cb08

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