Skip to main content

Local preflight for cloud AI coding agents

Project description

LAO — Local AI Orchestrator

Local preflight for cloud AI coding agents.
Your machine gathers evidence. Claude decides.


The Problem

Every time you run Claude Code, Cursor, or Codex on a task, the agent either:

  • Gets the entire repo dumped into context (expensive, noisy)
  • Has to guess which files are relevant (misses things, wastes tokens)
  • Sees your .env files and secrets (dangerous)

LAO solves this locally — before anything reaches the cloud.


What LAO Does

lao prep "fix failing auth test" --repo ./my-repo

In under 2 seconds, locally:

  1. Scans the repo with ripgrep
  2. Scores files by relevance (keyword match, import graph, path match, stacktrace parsing)
  3. Blocks secrets and .env files from leaving your machine
  4. Builds a token-optimized evidence pack for the agent

Result: Claude gets 1.7k tokens of the right context instead of 72k tokens of everything.


Quick Start

# Install
pip install lao
# or: pipx install lao

# Initialize in your repo
cd your-repo
lao init

# Prepare context for a task
lao prep "fix the failing auth session test"

# Output goes to .lao/context-pack.md
# Copy to Claude: cat .lao/context-pack.md | pbcopy

Optional but recommended:

# ripgrep — 10-100x faster search
brew install ripgrep       # macOS
apt install ripgrep        # Linux

# gitleaks — comprehensive secret scanning  
brew install gitleaks      # macOS

Example Output

lao prep "fix failing auth session test" --output compact
TASK: fix failing auth session test
TYPE:bug_diagnosis DIFFICULTY:cloud_recommended CONFIDENCE:70%
REPO:nextjs/typescript FILES:61 SELECTED:6
TOKENS:1.7k (raw:72k saved:98%)
BLOCKED:.env.local

=== EVIDENCE ===
--- src/auth/session.ts [keyword:15 path:12 error:10] ---
# L38-82
```ts
export function getSession(sessionId: string): Session | null {
  const session = sessionStore.get(sessionId)
  if (!session) return null
  
  const now = Math.floor(Date.now() / 1000)
  // BUG: should be <= not <
  if (session.expiresAt < now) {
    sessionStore.delete(sessionId)
    return null
  }
  return session
}

--- tests/auth/session.test.ts [keyword:15 path:12 test:4] ---

L28-55

it('returns null for expired session', () => {
  vi.setSystemTime(new Date(Date.now() + 3601 * 1000))
  const result = getSession(session.sessionId)
  expect(result).toBeNull()  // FAILS
})

SEND_TO:claude-sonnet


---

## Commands

| Command | Description |
|---------|-------------|
| `lao init` | Initialize lao in current repo |
| `lao prep "task"` | Prepare evidence pack for a task |
| `lao map` | Generate `.ai/` repo infrastructure |
| `lao mcp start` | Start MCP server (for Claude Code/Cursor) |
| `lao mcp config` | Show MCP configuration snippets |
| `lao check` | Check tool availability |
| `lao stats` | Show last run statistics |
| `lao show` | Show last context pack |

### `lao prep` options

```bash
lao prep "task" [options]

  --repo, -r PATH       Repo path (default: current directory)
  --context, -c TEXT    Extra context (paste error output, stacktrace)
  --output, -o FORMAT   markdown (default) | compact | json
  --no-cloud            Disable cloud routing recommendation
  --verbose, -v         Debug logging

Output formats

# Markdown file (default) — for manual copy/paste
lao prep "fix auth bug"

# Compact — token-efficient, for piping to agents
lao prep "fix auth bug" --output compact

# JSON — structured, for tooling
lao prep "fix auth bug" --output json

MCP Integration

LAO exposes three MCP tools so Claude Code, Cursor, and any MCP-compatible agent can call it directly.

Claude Code Setup

Add to .claude/settings.json in your repo:

{
  "mcpServers": {
    "lao": {
      "command": "uv",
      "args": ["run", "lao", "mcp", "start"],
      "cwd": "/path/to/lao"
    }
  }
}

Or run lao mcp config to get the exact snippet for your environment.

Available MCP Tools

Tool Description
lao_prep(task, repo_path?, extra_context?, output_format?) Prepare evidence pack
lao_map(repo_path?, force?) Generate .ai/ infrastructure
lao_status(repo_path?) Show last run stats

Cursor Setup

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "lao": {
      "command": "uv",
      "args": ["run", "lao", "mcp", "start"]
    }
  }
}

Codex / Other Agents

# Pipe compact output directly
lao prep "fix auth bug" --output compact | your-agent-cli

.ai/ Repo Infrastructure

lao map generates a .ai/ directory that makes your repo permanently agent-ready.

lao map

Creates:

.ai/
  manifest.yaml      # Stack, framework, entry points
  repo-map.yaml      # Module/feature → files mapping
  test-map.yaml      # Source file → test file mapping
  risk-zones.yaml    # Sensitive paths and why
  agent-rules.md     # Rules for AI agents (editable)

Commit .ai/ to git. Every agent that works in the repo benefits immediately.

Example manifest.yaml

repo:
  name: my-app
  framework: nextjs
  primary_language: typescript
  test_runner: vitest
  package_manager: pnpm
entry_points:
  - path: src/app/layout.tsx
    type: application
  - path: src/cli/index.ts
    type: cli
ai_hints:
  test_command: npx vitest run
  install_command: pnpm install

Example agent-rules.md

# Agent Rules for my-app

## Always
- Run tests before declaring a fix complete
- Keep changes minimal — do not refactor unless asked
- Check .ai/risk-zones.yaml before reading sensitive files

## Never
- Send .env* files or private keys to cloud context
- Add new dependencies without asking

Security

LAO is local-first and privacy-preserving by design:

  • .env* files are always blocked from leaving your machine
  • Private keys (*.pem, *.key, id_rsa) are always blocked
  • Secret scanning runs locally before any file is included
  • risk-zones.yaml documents exactly which paths are sensitive and why
  • Nothing is sent anywhere — LAO only writes to .lao/ and .ai/ locally

Default blocked patterns

.env, .env.*, .env.local, .env.production
**/*.pem, **/*.key, **/*.p12
**/id_rsa, **/id_ed25519
**/credentials*, **/*secret*, **/wallet*

Customize in .lao/config.yaml:

security:
  cloud_deny:
    - ".env*"
    - "**/*.pem"
    - "src/internal/pricing/**"   # add your own

Configuration

.lao/config.yaml is created by lao init. All fields are optional.

# Token budget for context pack
limits:
  max_files_in_context: 8        # Max files selected per run
  max_file_tokens: 6000          # Max tokens per file
  max_total_context_tokens: 30000

# Cloud routing
cloud:
  enabled: true
  preferred_model: claude-sonnet

# Local models (optional)
local:
  embeddings_enabled: false      # Enable with: lao index --with-embeddings
  local_llm_enabled: false

How It Works

lao prep "fix failing auth test"
    │
    ├── 1. Classify task          → bug_diagnosis, cloud_recommended
    ├── 2. ripgrep search         → 251 matches across 61 files
    ├── 3. Import graph           → session.ts imported by test file (+3.0)
    ├── 4. Stacktrace parsing     → error paths extracted from --context
    ├── 5. Score files            → path_match + keyword_match + entry_point
    ├── 6. Security policy        → .env.local BLOCKED
    ├── 7. Secret scan            → 0 secrets in selected files
    ├── 8. Build context pack     → 6 files, 1.7k tokens
    └── 9. Write outputs          → .lao/context-pack.md + report.json

Scoring signals

Signal Weight Source
keyword_match 3.0/match, cap 15 ripgrep hits in file
path_match 6.0/keyword keyword stem in file path
error_path 10.0 file mentioned in stacktrace
entry_point 8.0 / 4.0 __init__.py, main.py etc.
import_reference 3.0/ref imported by high-scoring file
repo_map_boost 5.0 .ai/repo-map.yaml match
doc_penalty -8.0 README, CHANGELOG etc.
generated_penalty -8.0 auto-generated files

Eval Results

Measured on 20 tasks across two repos (Next.js auth fixture + KMF Python library):

Metric Baseline LAO v0.1 Target
Context Recall 60.4% 78.3% ≥70%
Safety (no secrets) 100% 100% 100%
Tasks ≥75% recall 40% 50%

Roadmap

Phase Focus Status
Week 1 lao prep end-to-end, ripgrep, security ✅ Done
Week 2 Eval harness, import graph, scorer v2, MCP ✅ Done
Week 3 Persistent index, lao index --watch 🔜 Next
Phase 3 .ai/ as community standard 📋 Planned
Phase 4 PyPI release, public alpha 📋 Planned

Requirements

  • Python 3.11+
  • uv (recommended) or pip

Optional (improves quality):


GitHub Actions Integration

Add LAO to your CI pipeline with one file. Every PR gets a comment showing what would be sent to AI agents, and secrets are automatically flagged.

# .github/workflows/lao.yml
# Copy from: https://github.com/SynthexCapital/lao/blob/main/lao-github-action.yml

What the PR comment looks like:

## LAO Preflight Report

Task: fix failing auth session test
Recommended model: claude-sonnet

| Metric | Value |
|--------|-------|
| Files that would go to AI | 8 of 2,982 (99% filtered) |
| Tokens | 2,700 |
| Secrets | ✅ No secrets detected |

No secrets needed. LAO runs locally on the CI runner — your code never leaves the machine.

Set BLOCK_ON_SECRETS: "true" to automatically block PRs when secrets are detected.


License

MIT

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

lao-0.1.8.tar.gz (75.5 kB view details)

Uploaded Source

Built Distribution

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

lao-0.1.8-py3-none-any.whl (92.0 kB view details)

Uploaded Python 3

File details

Details for the file lao-0.1.8.tar.gz.

File metadata

  • Download URL: lao-0.1.8.tar.gz
  • Upload date:
  • Size: 75.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lao-0.1.8.tar.gz
Algorithm Hash digest
SHA256 e7ec0bd8b1ad9808885f66b83e439f0ff4ce98663210262b83e0d332b0ead86c
MD5 c14b63f16f17e866bc2097542220f474
BLAKE2b-256 a89371e3221d757bd8bebdf6b8ff48d14b114c55a2384aeba1ca38cf5ece9295

See more details on using hashes here.

File details

Details for the file lao-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: lao-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 92.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lao-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 6c0c0d699e931f525a3fd4d69e77ec64e3237a5185dcd6481a6416fab319cab6
MD5 e578d843e7d5cdc8052ad65d3910023d
BLAKE2b-256 dcc98c07cec23d0f1362ea1d6b12979f029973d84417d37ece8a582e682c9c57

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