{"id":43183031,"url":"https://github.com/web3infra-foundation/libra","last_synced_at":"2026-05-31T05:00:24.643Z","repository":{"id":317126318,"uuid":"1055612272","full_name":"web3infra-foundation/libra","owner":"web3infra-foundation","description":"Libra is evolving into an AI agent–native version control tools","archived":false,"fork":false,"pushed_at":"2026-05-25T05:05:59.000Z","size":24363,"stargazers_count":62,"open_issues_count":2,"forks_count":106,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-25T05:29:35.112Z","etag":null,"topics":["git","jj","pijul","rust","vcs"],"latest_commit_sha":null,"homepage":"https://libra.tools","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/web3infra-foundation.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-09-12T14:23:27.000Z","updated_at":"2026-05-25T05:04:23.000Z","dependencies_parsed_at":"2025-09-29T03:18:31.363Z","dependency_job_id":"1e8a8fa6-9deb-4349-b6bf-f53f42c81ef1","html_url":"https://github.com/web3infra-foundation/libra","commit_stats":null,"previous_names":["web3infra-foundation/libra"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/web3infra-foundation/libra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web3infra-foundation%2Flibra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web3infra-foundation%2Flibra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web3infra-foundation%2Flibra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web3infra-foundation%2Flibra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/web3infra-foundation","download_url":"https://codeload.github.com/web3infra-foundation/libra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web3infra-foundation%2Flibra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33719601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git","jj","pijul","rust","vcs"],"created_at":"2026-02-01T04:03:15.160Z","updated_at":"2026-05-31T05:00:24.571Z","avatar_url":"https://github.com/web3infra-foundation.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Libra](docs/image/banner.png)\n\nLibra is a partial implementation of a **Git** client, developed in **Rust**. The goal is **not** to build a perfect, 100% feature-complete reimplementation of Git (if you want that, take a look at [gitoxide](https://github.com/Byron/gitoxide)). Instead, Libra is evolving into an **AI agent–native version control system**.\n\nThe `libra code` command starts an interactive TUI (with a background web server and an MCP stdio surface) that is designed to be driven collaboratively by AI agents and humans. Libra also ships AI-native subcommands not found in Git: `code-control`, `automation`, `agent`, `usage`, `graph`, `sandbox`, and `publish`.\n\n---\n\n# AI Features\n\nThe AI surface is what makes Libra different from a vanilla Git client. The sections below cover where AI data lives, how to drive the AI runtime (`libra code`), which providers are supported, and the Libra-only subcommands that orchestrate the agent.\n\n## AI Data Storage\n\nLibra persists AI threads, runs, tasks, decisions, validation reports, tool-invocation events, patchset snapshots, automation history, captured external-agent sessions, and the live context window into the same repository storage directory that holds Git objects. Everything an AI agent does inside a Libra repository is durable, queryable, and replayable — no out-of-band state.\n\n### Repository Layout (`.libra/`)\n\n```\n.libra/\n├── libra.db              # SQLite — Git core + AI threads + AI runtime contracts\n├── vault.db              # libvault — encrypted secrets (signing keys, provider creds)\n├── objects/              # Local object store (loose + pack) — used when no remote backend is configured\n├── sessions/             # JSONL session store for AI conversations and file history\n└── ai/                   # Working files written by the AI runtime\n```\n\nIf `--separate-libra-dir \u003cdir\u003e` is passed to `libra init`, the entire storage directory is relocated; the working tree only keeps a pointer file.\n\n### SQLite Schema Groups\n\nThe single `libra.db` carries three logical schema groups (canonical bootstrap files: `sql/sqlite_20260309_init.sql` and `sql/sqlite_20260415_ai_runtime_contract.sql`; versioned forward + `_down.sql` migrations live in `sql/migrations/`):\n\n| Group | Tables |\n|-------|--------|\n| Git core | `config`, `config_kv`, `reference`, `reflog`, `rebase_state`, `object_index`, `schema_version` |\n| AI threads \u0026 scheduling | `ai_thread`, `ai_thread_participant`, `ai_thread_intent`, `ai_thread_provider_metadata`, `ai_scheduler_state`, `ai_scheduler_plan_head`, `ai_scheduler_selected_plan`, `ai_live_context_window` |\n| AI runtime contracts | `ai_index_intent_plan`, `ai_index_intent_task`, `ai_index_intent_context_frame`, `ai_index_plan_step_task`, `ai_index_run_event`, `ai_index_run_patchset`, `ai_index_task_run`, `ai_decision_proposal`, `ai_risk_score_breakdown`, `ai_validation_report` |\n\nThe publish Worker uses its own D1 schema in `sql/publish/` (independent from `libra.db`).\n\n### Inspecting AI Data\n\nEvery AI record is addressable via `cat-file`'s AI selectors. Pair with `--json=pretty` for machine-readable output:\n\n```bash\nlibra cat-file --ai-list ai_session                       # List captured AI sessions\nlibra cat-file --ai-list run                              # Runs (one per agent invocation)\nlibra cat-file --ai-list task                             # Tasks within a plan\nlibra cat-file --ai-list tool_invocation_event            # Every tool call the agent issued\nlibra cat-file --ai-list patchset_snapshot                # Patchset diffs proposed by the agent\nlibra --json=pretty cat-file --ai ai_session:\u003cai_session_id\u003e\n\nlibra graph \u003cthread_id\u003e [--repo /path/to/repo]            # TUI: navigate an AI thread version graph\nlibra usage                                               # Token + cost summary per provider/model\nlibra --json=pretty usage\nlibra db status                                           # Schema version and migration status\n```\n\n### Tiered Object Storage (S3 / R2 / MinIO)\n\nLibra can offload large objects (commits, blobs, packs, AI patchset snapshots) to S3-compatible object storage while keeping a local LRU cache. Tiering rules:\n\n- **Small objects** (`\u003c LIBRA_STORAGE_THRESHOLD`) — stored in both local and remote storage.\n- **Large objects** (`≥ LIBRA_STORAGE_THRESHOLD`) — stored remotely with a local LRU cache.\n\nIf `LIBRA_STORAGE_TYPE` is not set, Libra uses local-only storage under `.libra/objects`.\n\n| Variable                     | Description                                                   | Required (for S3/R2) | Default              |\n|-----------------------------|---------------------------------------------------------------|----------------------|----------------------|\n| `LIBRA_STORAGE_TYPE`        | Storage backend type: `s3` or `r2`                            | Yes                  | –                    |\n| `LIBRA_STORAGE_BUCKET`      | Bucket name                                                   | Yes                  | `libra`              |\n| `LIBRA_STORAGE_ENDPOINT`    | S3-compatible endpoint URL (required for R2)                  | Yes (for R2)         | AWS S3 default       |\n| `LIBRA_STORAGE_REGION`      | Region for bucket                                             | No                   | `auto`               |\n| `LIBRA_STORAGE_ACCESS_KEY`  | Access key ID                                                 | Yes                  | –                    |\n| `LIBRA_STORAGE_SECRET_KEY`  | Secret access key                                             | Yes                  | –                    |\n| `LIBRA_STORAGE_THRESHOLD`   | Size threshold in bytes for tiering                           | No                   | `1048576` (1 MB)     |\n| `LIBRA_STORAGE_CACHE_SIZE`  | Local cache size limit in bytes                               | No                   | `209715200` (200 MB) |\n| `LIBRA_STORAGE_ALLOW_HTTP`  | Allow HTTP (non-TLS) endpoints for testing (not for prod)     | No                   | `false`              |\n\n\u003e If any mandatory variable is invalid or empty, Libra automatically falls back to local storage and logs an error.\n\n### Cloud Backup \u0026 Restore (Cloudflare D1 + R2)\n\n`libra cloud` backs up the full repository state — Git objects, refs, **and** all AI tables — to Cloudflare D1 (metadata) plus R2 (objects). This is the canonical way to move a Libra repository (including its AI history) between machines.\n\n| Variable | Description | Required |\n|----------|-------------|----------|\n| `LIBRA_D1_ACCOUNT_ID` | Cloudflare Account ID | Yes |\n| `LIBRA_D1_API_TOKEN` | Cloudflare API Token | Yes |\n| `LIBRA_D1_DATABASE_ID` | Cloudflare D1 Database ID | Yes |\n\n```bash\nlibra cloud sync                       # Sync local repository (incl. AI data) to D1/R2\nlibra cloud restore --name \u003cNAME\u003e      # Restore by project name\nlibra cloud restore --repo-id \u003cID\u003e     # Restore by repo ID\nlibra cloud status                     # Show synchronization status\n\nlibra config cloud.name \u003cmy-unique-project-name\u003e   # Override the default (directory name) project name\n```\n\n### Vault-Backed Secrets\n\n`vault.db` (powered by [`libvault`](https://crates.io/crates/libvault)) stores AI provider keys, commit-signing GPG/SSH material, and arbitrary secrets used by the `automation` runtime. The unseal key is held outside the repository at `~/.libra/vault-keys/\u003crepoid\u003e`; the encrypted root token is recorded in repository config (`vault.roottoken_enc`).\n\nVault is enabled by default for every `libra init`; see [Vault-Backed Signing](#vault-backed-signing) for details.\n\n---\n\n## Libra Code Modes\n\nLibra Code supports three operation modes, each designed for different use cases.\n\n### 1. TUI Mode (Default)\n\nStarts an interactive Terminal User Interface along with a background web server.\nThis is the standard mode for developers who want to work directly in the terminal with AI assistance.\n\n```bash\nlibra code\n```\n\n- **Storage**: Uses the local project directory (`.libra/`) to isolate history and context per project.\n\n### 2. Web Mode\n\nRuns only the web server without the TUI.\nUseful for remote development or when you prefer using the browser interface exclusively.\n\n```bash\nlibra code --web\n```\n\n- **Storage**: Uses the local project directory (`.libra/`).\n\n### 3. Stdio Mode (MCP)\n\nRuns the Model Context Protocol (MCP) server over standard input/output.\nThis mode is designed for integration with AI clients like **Claude Desktop**.\n\n```bash\nlibra code --stdio\n```\n\n- **Storage**: Uses the local project directory (`.libra/`) for history persistence (same as TUI/Web modes).\n  The directory must be writable by the calling process (including sandboxed desktop AI apps).\n\n#### Claude Desktop Configuration\n\nTo use Libra with Claude Desktop, you must configure the MCP server to run within a valid Libra repository.\nUpdate your `claude_desktop_config.json` as follows:\n\n```json\n{\n  \"mcpServers\": {\n    \"libra\": {\n      \"command\": \"/path/to/libra\",\n      \"args\": [\"code\", \"--stdio\"],\n      \"cwd\": \"/path/to/your/libra/repo\"\n    }\n  }\n}\n```\n\n\u003e **Note**: The `cwd` (current working directory) must be set to the root of a valid Libra repository.\n\u003e If `libra code` is launched outside of a repository, it will exit with an error.\n\n#### Managed Runtime Migration\n\nThe legacy `claudecode` provider was removed. Use `libra code --provider codex`\nfor Libra's managed agent runtime, or `libra code --provider anthropic` for\ndirect Anthropic chat completions. Claude provider-session flags such as\n`--resume-session`, `--fork-session`, `--session-id`, and `--resume-at` are no\nlonger accepted; use Libra's canonical `--resume \u003cthread_id\u003e` flow for persisted\nsessions.\n\n## AI Provider Selection\n\nLibra Code supports multiple AI provider backends. Use the `--provider` and `--model` flags to choose which LLM to use:\n\n```bash\n# Gemini (default)\nlibra code --provider gemini\nlibra code --provider gemini --model gemini-2.5-flash\n\n# OpenAI\nlibra code --provider openai --model gpt-4o\n\n# Anthropic (direct chat completions)\nlibra code --provider anthropic --model claude-sonnet-4-6\n\n# DeepSeek\nlibra code --provider deepseek\nlibra code --provider deepseek --model deepseek-v4-pro --deepseek-thinking enabled --deepseek-reasoning-effort high\nlibra code --provider deepseek --model deepseek-v4-pro --deepseek-thinking enabled --deepseek-reasoning-effort high --deepseek-stream true\nlibra code --env-file .env.test --provider deepseek --model deepseek-v4-pro --deepseek-thinking enabled --deepseek-reasoning-effort high --deepseek-stream true\n\n# Kimi (Moonshot AI)\nlibra code --provider kimi\nlibra code --provider kimi --model kimi-k2.6\nlibra code --provider kimi --model kimi-k2.6 --kimi-thinking disabled\nlibra code --provider kimi --model moonshot-v1-128k\n\n# Zhipu (GLM)\nlibra code --provider zhipu --model glm-5\n\n# Ollama (local inference, no API key required, --model is required)\nlibra code --provider ollama --model llama3.2\nlibra code --provider ollama --model codellama\n\n# Ollama with a remote instance\nlibra code --provider ollama --model llama3.2 --api-base http://remote-host:11434/v1\nlibra code --provider ollama --model minimax-m2.7:cloud --api-base http://remote-host:11434/v1 --ollama-compact-tools\n\n# Ollama thinking control for reasoning models\nOLLAMA_THINK=false libra code --provider ollama --model qwen3.6\nlibra code --provider ollama --model qwen3.6 --ollama-thinking high\n```\n\n\u003e **Note**: The `--api-base` CLI flag is only honored for the `ollama` provider. Other providers accept custom base URLs through their respective environment variables (e.g. `OPENAI_BASE_URL`). Use `--env-file .env.test` to load provider keys from a dotenv-style file and override stale shell environment variables. DeepSeek reasoning fields are opt-in with `--deepseek-thinking enabled|disabled` and `--deepseek-reasoning-effort low|medium|high|max`; `xhigh` is accepted as an alias for `max`. DeepSeek streaming is opt-in with `--deepseek-stream true`; `--stream` is accepted as a DeepSeek-only alias. Kimi thinking can be overridden with `--kimi-thinking enabled|disabled`; omit it to use the selected model's default. Ollama requests stream `/api/chat` responses by default, include a per-request `request_id` in debug logs, and default to `think:false` to keep tool calls responsive; use `--ollama-thinking auto|off|on|low|medium|high` for one run, or set `OLLAMA_THINK=true`, `low`, `medium`, `high`, or `auto` as the environment default. `auto` omits the `think` field and lets Ollama decide. Use `--ollama-compact-tools` or `OLLAMA_COMPACT_TOOLS=true` for remote/cloud Ollama endpoints that return 503s when receiving Libra's full tool schemas.\n\n| Provider | Default Model | Auth Env Variable | Base URL Override | Provider-specific Tuning |\n|----------|--------------|-------------------|-------------------|-------------------------|\n| `gemini` | `gemini-2.5-flash` | `GEMINI_API_KEY` | — | — |\n| `openai` | `gpt-4o-mini` | `OPENAI_API_KEY` | `OPENAI_BASE_URL` | — |\n| `anthropic` | `claude-sonnet-4-6` | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` | — |\n| `deepseek` | `deepseek-chat` | `DEEPSEEK_API_KEY` | `--api-base` only (no env var) | `--deepseek-thinking`, `--deepseek-reasoning-effort`, `--deepseek-stream` |\n| `kimi` | `kimi-k2.6` | `MOONSHOT_API_KEY` | `MOONSHOT_BASE_URL` | `--kimi-thinking` |\n| `zhipu` | `glm-5` | `ZHIPU_API_KEY` | `ZHIPU_BASE_URL` | — |\n| `ollama` | *(requires `--model`)* | `OLLAMA_API_KEY` for direct Cloud API | `OLLAMA_BASE_URL`, `--api-base` | `OLLAMA_THINK`, `OLLAMA_COMPACT_TOOLS`, `--ollama-thinking`, `--ollama-compact-tools` |\n\n`libra code` tries the Brave Search API for the `web_search` tool when `BRAVE_SEARCH_API_KEY` is set in the process environment or stored as `vault.env.BRAVE_SEARCH_API_KEY`; if Brave is not configured or the request fails, it falls back to DuckDuckGo HTML search. The session network policy must still allow outbound access.\n\n---\n\n## AI-Native Extensions\n\nThese subcommands are Libra-only (not present in Git) and form the AI-agent surface around the Git core.\n\n### `libra automation` — Rule-Based Automation\n\nRun scheduled (cron-driven) or ad-hoc automation rules. Rules live in repository config; the runner enforces a command safety preflight before any live shell action is spawned. History is persisted into the AI tables so a previous run can be replayed.\n\n```bash\nlibra automation list                                 # List configured rules\nlibra automation run                                  # Dry-run all due cron rules\nlibra automation run --rule my-rule                   # Force-run a single rule\nlibra automation run --now 2026-05-23T12:00:00Z       # Simulate \"now\" when evaluating cron triggers\nlibra automation run --live                           # Actually spawn shell actions (subject to preflight)\nlibra automation history --limit 50                   # Recent automation history\nlibra --json=pretty automation list                   # Structured JSON output for agents\n```\n\n### `libra agent` — External-Agent Capture\n\nCapture sessions and checkpoints from external coding agents (Claude Code, Gemini, ...) into `refs/libra/agent-traces`. Useful for replaying agent transcripts and pushing traces to a shared remote so the team can audit what an external agent actually did.\n\n```bash\nlibra agent status                                    # Captured-session counts and recent checkpoints\nlibra agent enable --agent claude                     # Install hooks for one agent\nlibra agent enable                                    # Enable every stable external agent\nlibra agent disable --agent claude\nlibra agent session list\nlibra agent checkpoint list\nlibra agent checkpoint show \u003cid\u003e\nlibra agent checkpoint rewind \u003cid\u003e                    # Replay as a JSONL transcript\nlibra agent clean [--all]                             # Drop temporary checkpoints from stopped sessions\nlibra agent doctor                                    # Diagnose hook installation and capture state\nlibra agent push [--remote origin]                    # Push refs/libra/agent-traces\nlibra agent rpc list                                  # Discover libra-agent-\u003cname\u003e RPC binaries on PATH\nlibra agent rpc invoke \u003cslug\u003e \u003cmethod\u003e --params '{}'\n```\n\n### `libra publish` — Read-Only Cloudflare Worker Publishing\n\nPublish a snapshot of one or more refs to Cloudflare D1 (metadata) + R2 (objects) and serve them through a thin read-only Worker. Designed for sharing AI-generated artifacts or read-only mirrors of a repository.\n\n```bash\nlibra publish init --slug \u003cslug\u003e --clone-domain \u003cdomain\u003e   # Materialise the local Worker scaffold\nlibra publish status                                       # Inspect local template / D1 ref drift\nlibra publish status --site-id \u003cuuid\u003e\nlibra publish sync                                         # Sync default refs to D1/R2\nlibra publish sync --dry-run\nlibra publish sync --ref refs/heads/main\nlibra publish sync --force                                 # Re-upload everything, ignoring CAS\nlibra publish sync --allow-sensitive-path \u003cpath\u003e           # Override the deny list for a private site\nlibra publish deploy                                       # Build and deploy the Worker\nlibra publish deploy --skip-deploy                         # Build only\nlibra publish unpublish --site-id \u003cuuid\u003e --yes\n```\n\n### `libra sandbox` — AI Sandbox Diagnostics\n\nInspect the command-safety sandbox used by AI tool execution: enforcement mode, network policy, seccomp/seatbelt status, and writable-root tmpdir layout. Every shell tool invoked by the AI runtime passes through this sandbox before it runs.\n\n```bash\nlibra sandbox status\nlibra sandbox inspect --command \"\u003ccmd\u003e\"               # Dry-run the safety classifier on a command\n```\n\nRelevant environment toggles:\n\n- `LIBRA_SANDBOX_ENFORCEMENT` — `disabled` / `warn` / `enforce`\n- `LIBRA_SANDBOX_NETWORK_DISABLED` — block outbound network for sandboxed tools\n- `LIBRA_LINUX_SANDBOX_EXE`, `LIBRA_USE_LINUX_SANDBOX_BWRAP` — Linux bwrap integration\n- `LIBRA_SECCOMP_POLICY` — override the bundled `template/seccomp-default.json` allow-list\n\n### `libra code-control` and `libra graph`\n\n`code-control` drives an existing local `libra code` TUI from another process via a lease-based automation API — useful for AI-agent-in-the-loop scripts. `graph` opens a TUI for inspecting an AI thread's version graph.\n\n```bash\nlibra code-control --help\nlibra graph \u003cthread_id\u003e [--repo /path/to/repo]\n```\n\n### `libra usage` — AI Provider/Model Usage\n\nReport token usage and cost across providers and models, persisted by the AI runtime.\n\n```bash\nlibra usage                                           # Summary across all providers\nlibra --json=pretty usage                             # Structured JSON output\n```\n\n---\n\n## Optional FUSE Backend\n\nLibra Code can use a FUSE overlay backend for temporary Agent task worktrees on\nUnix platforms. This backend is optional: if FUSE is unavailable or fails its\nhealth check, Libra logs a warning and falls back to the copy backend.\n\n### macOS\n\nInstall [macFUSE](https://macfuse.github.io/) before using the FUSE backend.\nThe upstream project recommends downloading the latest installer from the\n[macFUSE website or GitHub releases](https://github.com/macfuse/macfuse/wiki/Getting-Started).\n\nHomebrew can also install the cask for development machines:\n\n```bash\nbrew install --cask macfuse\n```\n\nFollow any macOS System Settings prompts to allow macFUSE if required by the\nselected backend. After installation, verify that the mount helper expected by\nLibra's FUSE library exists:\n\n```bash\ntest -x /Library/Filesystems/macfuse.fs/Contents/Resources/mount_macfuse\n```\n\nIf Libra logs `macfuse mount binary not found`, macFUSE is not installed or the\nmount helper is not present at the expected path. Install or repair macFUSE, then\nstart `libra code` again.\n\n### Linux\n\nInstall FUSE 3 with your distribution package manager. Common package names are:\n\n```bash\n# Debian / Ubuntu\nsudo apt-get update\nsudo apt-get install -y fuse3\n\n# Fedora / RHEL\nsudo dnf install fuse3\n\n# Arch Linux\nsudo pacman -S fuse3\n```\n\nVerify that `fusermount3` is available:\n\n```bash\ncommand -v fusermount3\n```\n\nIf the command is missing, Libra cannot use the unprivileged FUSE mount path and\nwill use the copy backend instead.\n\n---\n\n# Git-Compatible Features\n\nLibra's Git surface stays compatible enough to fetch from / push to standard Git servers (GitHub, Gitea, …). The per-command compatibility status (`supported` / `partial` / `unsupported` / `intentionally-different`) is tracked in [`COMPATIBILITY.md`](COMPATIBILITY.md).\n\n## Features\n\n### Clean Code\n\nThe codebase is designed to be clean and easy to read, making it maintainable and approachable for developers of all skill levels.\n\n### Cross-Platform\n\n- [x] Windows\n- [x] Linux\n- [x] macOS\n\n### Compatibility with Git\n\nLibra's core implementation is essentially compatible with **Git** (developed with reference to Git's own documentation), including support for on-disk formats such as:\n\n- `objects`\n- `index`\n- `pack`\n- `pack-index`\n\nThis allows Libra to interact seamlessly with Git servers (for example, `push` and `pull` work with standard Git remotes).\n\n### Differences from Git\n\nWhile maintaining compatibility with Git, Libra intentionally diverges in some areas:\n\n- Uses an **SQLite** database to manage loosely structured files such as `config`, `HEAD`, and `refs`, providing unified and transactional management instead of plain-text files.\n- Records AI threads, runs, decisions, and patchset snapshots in the same SQLite database (see [AI Data Storage](#ai-data-storage)).\n- Object storage can be tiered into S3/R2; backups go to Cloudflare D1/R2.\n\n## grep\n\n`grep` searches tracked working-tree files, the index (`--cached`), or committed trees (`--tree \u003crevision\u003e`) using regular expressions by default. It also supports fixed-string mode, multiple explicit patterns, pattern files, and requiring all patterns to match within the same file.\n\n```bash\n# Search tracked working-tree files with a regex\nlibra grep \"foo.*bar\"\n\n# Search with multiple explicit patterns\nlibra grep -e alpha -e beta\n\n# Require every pattern to appear in the same file\nlibra grep --all-match -e alpha -e beta\n\n# Search the staged/index version of tracked files\nlibra grep --cached \"needle\"\n\n# Search a specific revision or branch\nlibra grep --tree HEAD \"needle\"\nlibra grep --tree main \"needle\"\n\n# Read patterns from a file\nlibra grep -f patterns.txt\n```\n\n## Bisect — Binary Search for Bugs\n\nLibra implements a `bisect` subcommand that uses binary search to find the commit that introduced a bug. It is broadly compatible with `git bisect`.\n\n### Basic Usage\n\n```bash\n# Start a bisect session\nlibra bisect start\n\n# Mark the current commit as bad (contains the bug)\nlibra bisect bad\n\n# Mark a known-good commit\nlibra bisect good \u003ccommit\u003e\n\n# After marking, bisect will checkout commits for you to test\n# Continue marking commits as good/bad until the culprit is found\n\n# End the session and restore your original HEAD\nlibra bisect reset\n```\n\n### Quick Start with Known Bounds\n\n```bash\n# Start with both bad and good commits specified\nlibra bisect start HEAD~10 HEAD~20  # HEAD~10 is bad, HEAD~20 is good\n```\n\n### Subcommands\n\n- `libra bisect start [\u003cbad\u003e [\u003cgood\u003e]]` – start a new bisect session\n- `libra bisect bad [\u003crev\u003e]` – mark a commit as bad (contains the bug)\n- `libra bisect good [\u003crev\u003e]` – mark a commit as good (bug-free)\n- `libra bisect skip [\u003crev\u003e]` – skip the current commit (untestable)\n- `libra bisect reset [\u003crev\u003e]` – end the session and restore original HEAD\n- `libra bisect log` – show the current bisect state\n\n### Safety Features\n\nLibra's bisect implementation includes several safety guards:\n\n- **Clean working tree required**: Bisect will not start if you have uncommitted changes (including ignored files like `.env`)\n- **Bare repository protection**: Bisect is blocked in bare repositories (no working tree)\n- **State preserved until reset**: After finding the culprit, bisect state is preserved so you can run `bisect reset` to restore your original branch\n- **Branch restoration**: `bisect reset` restores you to your original branch, not a detached HEAD\n\n## Worktree Management\n\nLibra implements a `worktree` subcommand that is broadly compatible with `git worktree`, allowing you to manage multiple working directories attached to the same repository storage.\n\nUnlike `git worktree remove`, Libra does **not** delete worktree directories on disk by default.\n\nSupported subcommands:\n\n- `libra worktree add \u003cpath\u003e` – create a new linked working tree at `\u003cpath\u003e`\n- `libra worktree list` – list all registered working trees (including the main worktree)\n- `libra worktree lock \u003cpath\u003e [--reason \u003cmsg\u003e]` – mark a worktree as locked with an optional reason\n- `libra worktree unlock \u003cpath\u003e` – unlock a previously locked worktree\n- `libra worktree move \u003csrc\u003e \u003cdest\u003e` – move a worktree directory to a new location\n- `libra worktree prune` – prune missing or non-existent worktrees from the registry\n- `libra worktree remove \u003cpath\u003e` – remove a worktree from the registry without deleting its directory on disk (the main worktree cannot be removed)\n- `libra worktree umount \u003cpath\u003e [--cleanup]` – unmount a FUSE worktree or stale Agent task worktree mountpoint\n- `libra worktree repair` – repair inconsistent worktree state if the registry and directories get out of sync\n\n## Vault-Backed Signing\n\nLibra supports repository-local vault initialization for commit signing:\n\n```bash\nlibra init [--separate-libra-dir \u003cdir\u003e] [\u003crepo_directory\u003e]\n```\n\nVault is enabled by default for all `libra init` invocations — no extra flag is needed.\n\nWhen vault is enabled:\n\n- A vault database (`vault.db`) is created in the repository storage directory (`.libra/` or the directory passed via `--separate-libra-dir`).\n- Libra generates a signing key and enables `vault.signing=true`.\n- The vault unseal key is stored outside the repository at `~/.libra/vault-keys/\u003crepoid\u003e`.\n- The encrypted root token is stored in repository config (`vault.roottoken_enc`).\n\nSecurity note:\n\n- Libra no longer falls back to storing the unseal key inside repository config.\n- If the home directory is not writable/usable, `libra init` fails with a fatal error.\n\nTroubleshooting:\n\n- Ensure `HOME` (or `USERPROFILE` on Windows) points to a writable directory.\n- In container/CI environments, explicitly set `HOME` to a writable path before running `libra init`.\n\nKey management commands:\n\n```bash\n# Print current signing GPG public key (for GitHub GPG key settings)\nlibra config get vault.gpg.pubkey\n\n# Generate a repo-local SSH key for a configured remote\nlibra config generate-ssh-key --remote origin\n\n# Print the SSH public key for a configured remote\nlibra config get vault.ssh.origin.pubkey\n\n# Generate (or rotate) vault GPG signing key and print public key\nlibra config generate-gpg-key [--name \u003cuser\u003e] [--email \u003cmail\u003e]\n```\n\nSee `docs/commands/config.md` for the full `libra config` command reference and migration notes.\n\n### GitHub End-to-End Verification (libvault + Git conversion)\n\nThe following flow validates:\n\n- `libvault` integration with Libra storage (`.libra/vault.db` + config metadata in SQLite)\n- Conversion from Git repository format to Libra repository format\n- Vault-backed GPG signing on commit\n- SSH push from Libra to GitHub\n\n```bash\n# 1) Clone an existing GitHub repository locally with Git (SSH).\n#    (This step can use your existing SSH credential.)\ngit clone git@github.com:\u003cowner\u003e/\u003crepo\u003e.git /tmp/\u003crepo\u003e-git\n\n# 2) Convert the cloned Git repository into a Libra repository and\n#    initialize vault in the same command.\nmkdir -p /tmp/\u003crepo\u003e-libra\ncd /tmp/\u003crepo\u003e-libra\nlibra init --from-git-repository /tmp/\u003crepo\u003e-git\n\n# 3) Export vault public keys and register them in GitHub settings:\n#    - GPG key: GitHub -\u003e Settings -\u003e SSH and GPG keys -\u003e New GPG key\n#    - SSH key: GitHub -\u003e Settings -\u003e SSH and GPG keys -\u003e New SSH key\nlibra config get vault.gpg.pubkey\nlibra config generate-ssh-key --remote origin\nlibra config get vault.ssh.origin.pubkey\n\n# 4) Make sure origin points to GitHub SSH URL in Libra config.\nlibra remote set-url origin git@github.com:\u003cowner\u003e/\u003crepo\u003e.git\n\n# 5) Create a signed commit and push through SSH.\necho \"vault e2e\" \u003e vault-e2e.txt\nlibra add vault-e2e.txt\nlibra commit -m \"feat(vault): verify signed commit to GitHub\"\nlibra push origin master\n```\n\nVerification points:\n\n- `libra commit` should produce a commit object containing `gpgsig`.\n- `libra push` should succeed over SSH (`git@github.com:...`).\n- The commit should appear in GitHub with signature metadata.\n\nNote:\n\n- For the very first `git clone` in step 1, Git may still use your existing SSH credentials.\n  After step 3, Libra fetch/push uses the vault-generated key for this repository.\n\n## 🚧 Pending Git commands (not yet supported)\n\nThe following Git top-level commands are currently **not implemented** in Libra (excluding `submodule` and `subtree`, which are intentionally omitted):\n\n- `gc` – garbage-collect unreachable objects and pack files\n- `prune` – remove loose objects that are no longer reachable\n- `maintenance` – periodic maintenance tasks\n- `pack-objects` / `unpack-objects` – pack and unpack object collections\n- `remote-show` – show detailed remote info\n- `fetch-pack` / `push-pack` – low-level fetch/push operations\n- `filter-branch` (or `git filter-repo`) – rewrite history\n- `notes` – attach arbitrary metadata to objects\n- `archive` – create tar/zip archives of tree snapshots\n- `rebase --autosquash` / `rebase --reapply-cherry-picks` – advanced rebase options\n\nThese commands are slated for future implementation according to the project roadmap. The full per-command compatibility status (`supported` / `partial` / `unsupported` / `intentionally-different`) is tracked in [`COMPATIBILITY.md`](COMPATIBILITY.md).\n\n## Note on Submodule and Subtree\n\nLibra does **not** provide the `submodule` or `subtree` commands. Because Libra stores objects in an S3-compatible backend and is designed around a **Monorepo** layout with **Trunk-based Development**, the use-cases that `git submodule`/`git subtree` address (embedding separate repositories) are handled differently – large external data lives in S3 and all code lives in a single repository.\n\nThis design choice simplifies dependency management and aligns with Libra's goal of supporting ultra-large repositories while keeping a single source of truth.\n\n---\n\n## Error Reporting\n\nCLI failures use stable exit codes and stable error codes. When `stderr` is not a TTY, Libra also appends a JSON stderr report for agents and wrappers. Set `LIBRA_ERROR_JSON=1` to force that structured report in interactive terminals.\nRun `libra help error-codes` for the built-in CLI reference.\nSee [docs/error-codes.md](docs/error-codes.md).\n\n---\n\n## Contributing \u0026 Development\n\nBefore submitting a Pull Request, please ensure your code passes the following checks:\n\n```bash\n# Run clippy with all warnings treated as errors\ncargo clippy --all-targets --all-features -- -D warnings\n\n# Check code formatting (requires nightly toolchain)\ncargo +nightly fmt --all --check\n```\n\nBoth commands must complete without any warnings. The clippy check treats all warnings as errors, and the formatter check ensures code follows the project style guide.\n\nIf the formatting check fails, you can automatically fix formatting issues by running:\n\n```bash\ncargo +nightly fmt --all\n```\n\n## Run on Windows\n\nIf you are building Libra on Windows for the first time, install OpenSSL before running\n`cargo build` or `cargo test`. The easiest setup is to use a precompiled OpenSSL package:\n\u003chttps://slproweb.com/products/Win32OpenSSL.html\u003e\n\nRecommended setup:\n\n1. Install a 64-bit OpenSSL build that matches the default Rust Windows target\n   `x86_64-pc-windows-msvc`.\n2. Note the installation directory, for example `D:\\OpenSSL-Win64`.\n3. Create `.cargo/config.toml` in the project root if it does not already exist.\n4. Add OpenSSL environment overrides so Cargo and dependent build scripts can find the\n   headers and libraries.\n\nProject layout:\n\n```text\n.cargo/\n  config.toml\n```\n\nExample `.cargo/config.toml`:\n\n```toml\n[env]\nOPENSSL_DIR = \"D:\\\\OpenSSL-Win64\"\nOPENSSL_LIB_DIR = \"D:\\\\OpenSSL-Win64\\\\lib\\\\VC\\\\static\"\nOPENSSL_INCLUDE_DIR = \"D:\\\\OpenSSL-Win64\\\\include\"\nOPENSSL_NO_VENDOR = \"1\"\n```\n\nNotes:\n\n- Update the paths if OpenSSL is installed in a different directory.\n- If `.cargo/config.toml` already exists, merge these entries instead of replacing the file.\n- Some OpenSSL installers place libraries in a different subdirectory. If `VC\\\\static` does\n  not exist in your installation, point `OPENSSL_LIB_DIR` at the directory that contains the\n  `.lib` files for your installation.\n- After updating the config, open a new terminal and verify the setup with:\n\n```bash\ncargo build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweb3infra-foundation%2Flibra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweb3infra-foundation%2Flibra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweb3infra-foundation%2Flibra/lists"}