Files
Pyra/CLAUDE.md
T
curo1305 27b32cb4d1 docs: CLAUDE.md with full 5-stage roadmap and README
CLAUDE.md: architecture table, security rules, all module descriptions,
roadmap Stages 1-5, adding-provider guide, commit convention.
README.md: quick start, provider table, command reference, security overview.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:56:08 +02:00

5.2 KiB

Pyra — Developer Guide

What Is This

Pyra is a personal AI assistant CLI combining a multi-provider AI chat interface with an automation/skills system (Stage 2+) and an encrypted vault (Stage 3+).

Project Roadmap

Stage 1 — Core CLI (current)

Working pyra executable with provider setup wizard, streaming chat REPL, .md-based memory in ~/.pyra/memory/, and hard security boundaries around the vault.

Stage 2 — Skills / Automations

Shell (.sh), PowerShell (.ps1), and Python (.py) scripts in ~/.pyra/skills/. The AI can suggest running a skill, but execution requires explicit user approval (y/n prompt). No skill can access the vault. Skills are discovered by the pyra CLI, not by the AI.

Stage 3 — Vault Encryption

Encrypt ~/.pyra/vault/secrets/ using age (or GPG fallback). Pyra decrypts in memory at call time only — no plaintext ever written to disk after initial setup. Secret rotation support. Per-key passphrases optional.

Stage 4 — Security Audit Sub-agent

A separate pyra security audit command that spins up a sandboxed AI agent whose sole job is scanning for vulnerabilities: prompt injection in memory files, unexpected vault access attempts in security.log, outdated dependency CVEs, permission drift on ~/.pyra/. Report written to ~/.pyra/security_audit.md (not AI-readable during normal chat).

Stage 5 — Web UI / Advanced Features

Optional local web interface (FastAPI + HTMX or similar). Embedding-based memory search (ChromaDB or sqlite-vec). Scheduled automations via cron-style skill scheduling. Multi-profile support (work vs personal).


Architecture

Source: src/pyra/

Module Purpose
cli.py Click entrypoint. Subcommands: setup, chat, memory
setup/providers.py Provider registry — pure data, no I/O
setup/wizard.py questionary-based interactive setup wizard
config/schema.py Pydantic v2 models — no API keys, only provider_id/model/base_url
config/manager.py ruamel.yaml round-trip config read/write, chmod 600 enforced
config/dirs.py bootstrap() — creates ~/.pyra/ tree, checks vault sentinel every startup
chat/session.py prompt_toolkit REPL loop, slash commands, calls vault reader inline
chat/renderer.py Live streaming markdown via rich, injection warning panel, key redaction
chat/history.py Conversation list, token budget trimming, system prompt construction
memory/reader.py list_memories(), read_memory(), load_context_for_session()
memory/writer.py write_memory(), append_memory() — relative names only, no traversal
memory/index.py Auto-regenerate MEMORY_INDEX.md on every write
vault/reader.py get_key(provider_id) — sole accessor of vault/secrets/api_keys.json
vault/writer.py set_key(), delete_key() — only called from setup wizard
security/boundaries.py assert_safe_path(), check_vault_lock(), BLOCKED_PREFIXES
security/injection.py scan_response() — 15 regex patterns, 4 categories, logs to security.log
utils/paths.py pyra_home(), ensure_dir(), safe_chmod(), expand()

Runtime: ~/.pyra/

~/.pyra/
├── config.yaml          chmod 600  ← provider_id, model, base_url ONLY
├── security.log         chmod 600  ← injection event log
├── memory/              chmod 700
│   ├── user/profile.md
│   ├── context/
│   ├── knowledge/
│   └── MEMORY_INDEX.md
├── skills/              chmod 700  ← Stage 2
│   ├── bash/
│   ├── powershell/
│   └── python/
└── vault/               chmod 700  ← AI CANNOT ACCESS
    ├── .vault_lock      chmod 400  ← sentinel; missing = refuse to start
    └── secrets/
        └── api_keys.json  chmod 400  ← ALL API keys

Security Rules (never break these)

  1. Never pass config file contents into a system prompt — config may reveal provider/model
  2. Never bypass assert_safe_path() — not even in tests (use tmp_pyra_home fixture instead)
  3. Always chmod 600/400 after writing any file in ~/.pyra/
  4. No shell execution from AI-generated text — ever (Stage 2 uses explicit approval gates)
  5. vault/reader.py and vault/writer.py are the only modules that import from pyra.vault
  6. API key retrieved inline at call time — never stored as an instance variable or logged

Adding a New Provider

Edit src/pyra/setup/providers.py. Add a new Provider dataclass entry with all required fields. litellm handles dispatch automatically via the litellm_prefix field. Add a test in tests/unit/test_providers.py to verify the new entry.

Installing for Development

uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pyra setup

Or with pip:

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pyra setup

Running Tests

pytest tests/ -v                           # all unit + security tests
pytest tests/integration/test_lmstudio.py  # requires LM Studio at localhost:1234

Commit Convention

feat(module): short description
fix(module): short description
test: description
docs: description
chore: description