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:
- 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.
- Pre-push risk check — before you push,
perla preflightmaps 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
- Issues: https://github.com/Matiyas-H/Perla-cli/issues
- LocAgent platform: https://locagent.dev
- License: Apache 2.0 — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file perla-0.1.18.tar.gz.
File metadata
- Download URL: perla-0.1.18.tar.gz
- Upload date:
- Size: 285.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cfe6938cb3dc9facf976095e8acbe35c92b1350eaab94a0f6b2409ba28624f8
|
|
| MD5 |
90d2ae64d0d5bafe8c5ab5bc753966c4
|
|
| BLAKE2b-256 |
95a20ead7647723cfc6f47c763a48400dfb34d34bb5e0fb5665ab1483df4c6fc
|
File details
Details for the file perla-0.1.18-py3-none-any.whl.
File metadata
- Download URL: perla-0.1.18-py3-none-any.whl
- Upload date:
- Size: 217.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
793a3e218c6bce0060b634e82e46df73dc6c25a6bc9b868566ab56bb39dddac1
|
|
| MD5 |
f36b1fa0039d30cdb473b203f31d1c1d
|
|
| BLAKE2b-256 |
c5ba0720259f7f49d22cd284f2e613ceb2a29d51bbf7fd091b260444bb4bca09
|