# AGENTS.md Documentation for AI agents and automated tools working with the ngit codebase. ## Project Overview **ngit** is a nostr plugin for git that enables decentralized code collaboration using the nostr protocol. - **Language**: Rust - **Type**: Command-line tool with git integration - **Architecture**: Two main binaries (`ngit` and `git-remote-nostr`) with shared library code - **Key Dependencies**: nostr-sdk, git2, clap, tokio ### Core Concepts 1. **Nostr Integration**: Uses nostr for repository identification, discovery, state management, and collaboration (PRs, issues) 2. **Git Server Agnostic**: Still requires git servers for data storage, but they're interchangeable 3. **Decentralized**: Multiple relays and git servers can be used for redundancy 4. **URL Format**: `nostr:///` ## Project Structure ``` ngit/ ├── src/ │ ├── bin/ │ │ ├── git_remote_nostr/ # Git remote helper implementation │ │ │ ├── capabilities.rs │ │ │ ├── fetch.rs │ │ │ ├── list.rs │ │ │ ├── main.rs │ │ │ └── push.rs │ │ └── ngit/ # Main CLI tool │ │ ├── main.rs │ │ └── sub_commands/ │ └── lib/ # Shared library code │ ├── git/ # Git operations │ ├── login/ # User authentication │ ├── client.rs # Nostr client │ ├── fetch.rs # Fetch operations │ ├── git_events.rs # Git event handling │ ├── list.rs # List operations │ ├── push.rs # Push operations │ ├── repo_ref.rs # Repository references │ ├── repo_state.rs # Repository state │ └── utils.rs # Utilities ├── tests/ # Integration tests ├── test_utils/ # Test utilities and helpers └── git_hooks/ # Git hooks for development ``` ## Key Files and Their Purposes ### Core Library (`src/lib/`) - **`repo_ref.rs`**: Repository reference handling, URL parsing, grasp server detection - Functions: `is_grasp_server_in_list()`, `is_grasp_server_clone_url()`, `normalize_grasp_server_url()` - Critical for identifying and validating repository URLs - **`repo_state.rs`**: Manages repository state (refs, commits, etc.) - **`client.rs`**: Nostr client wrapper and relay communication - **`git_events.rs`**: Handles git-related nostr events - **`push.rs`**: Push operations to git servers and nostr relays - **`fetch.rs`**: Fetch operations from git servers ### Binaries - **`git-remote-nostr`**: Git remote helper that enables git to work with nostr:// URLs - **`ngit`**: Main CLI tool for managing nostr repositories ## Development Guidelines ### Code Style - Follow Rust standard formatting (`rustfmt.toml` is configured) - Run `cargo fmt` before committing - Run `cargo clippy` to catch common issues - Use `anyhow::Result` for error handling - Prefer explicit error messages with context ### Testing ```bash # Run all tests cargo test # Run specific test cargo test test_name # Run tests with output cargo test -- --nocapture # Run integration tests only cargo test --test ngit_init ``` ### Important Testing Notes 1. **URL Comparison**: When comparing git server URLs, be aware of normalization: - `is_grasp_server_in_list()`: Compares full URLs (including repo path) - `normalize_grasp_server_url()`: Extracts server part only (strips npub and path) 2. **Test Structure**: Integration tests are in `tests/`, unit tests are in module files ### Building ```bash # Development build cargo build # Release build cargo build --release # Binaries will be in target/debug/ or target/release/ # - ngit # - git-remote-nostr ``` ## Common Tasks for Agents ### Adding New Features 1. **Identify the correct module**: - Git operations → `src/lib/git/` - Nostr operations → `src/lib/client.rs`, `src/lib/git_events.rs` - CLI commands → `src/bin/ngit/sub_commands/` - Remote helper → `src/bin/git_remote_nostr/` 2. **Add tests**: Always add tests for new functionality 3. **Update error handling**: Use `anyhow::Context` for error messages 4. **Check dependencies**: Avoid adding unnecessary dependencies ### Debugging Issues 1. **Check test failures**: Run `cargo test` to identify failing tests 2. **Review error context**: Look at the full error chain with `.context()` 3. **Examine URL handling**: Many issues relate to URL parsing/normalization - Check `repo_ref.rs` for URL-related functions - Verify grasp server detection logic 4. **Trace nostr events**: Check event creation and publishing in `git_events.rs` ### Refactoring 1. **Maintain backward compatibility**: This is a CLI tool users depend on 2. **Update all call sites**: Use `cargo check` to find all references 3. **Run full test suite**: Ensure nothing breaks 4. **Check integration tests**: These test real-world scenarios ## Architecture Patterns ### Error Handling ```rust use anyhow::{Context, Result}; fn example() -> Result<()> { something() .context("descriptive error message")?; Ok(()) } ``` ### Async Operations - Uses `tokio` runtime for async operations - Nostr operations are async - Git operations are mostly sync ### Configuration - User config stored in platform-specific directories (via `directories` crate) - Repository config in `.git/config` and `ngit.yaml` ## Important Invariants ### URL Handling 1. **Grasp Server URLs**: Must contain npub in path format: `/{npub}/` 2. **Nostr URLs**: Format: `nostr:///` 3. **Normalization**: Different functions normalize differently: - Full URL comparison: Use direct string comparison with `trim_end_matches('/')` - Server identification: Use `normalize_grasp_server_url()` ### Git Integration 1. **Remote helper protocol**: Must follow git's remote helper protocol exactly 2. **Ref naming**: PRs use `pr/` prefix 3. **State sync**: Must keep git refs in sync with nostr events ## Dependencies to Be Aware Of ### Critical Dependencies - **nostr**: Core nostr protocol implementation - **git2**: Git operations via libgit2 - **tokio**: Async runtime - **anyhow**: Error handling ### Optional Features Check `Cargo.toml` for feature flags and optional dependencies. ## Testing Strategy ### Unit Tests - Located in same file as code (`#[cfg(test)] mod tests`) - Test individual functions in isolation - Example: `is_grasp_server_in_list` tests in `repo_ref.rs` ### Integration Tests - Located in `tests/` directory - Test full workflows (init, push, fetch, etc.) - Require test utilities from `test_utils/` ### Test Utilities - Mock relay implementation - Git repository setup helpers - Located in `test_utils/` ## Common Pitfalls ### 1. URL Normalization **Problem**: Using wrong normalization function leads to incorrect comparisons. **Solution**: - For full URL comparison: Direct string comparison - For server identification: Use `normalize_grasp_server_url()` ### 2. Async/Sync Boundaries **Problem**: Mixing async and sync code incorrectly. **Solution**: Use `tokio::runtime::Runtime` or proper async context. ### 3. Git State **Problem**: Git state getting out of sync with nostr events. **Solution**: Always update both git refs and publish nostr events atomically. ## Contribution Workflow 1. **Clone**: Use ngit itself to clone: `nostr://dan@gitworkshop.dev/relay.damus.io/ngit` 2. **Branch**: Create a branch with `pr/` prefix for pull requests 3. **Test**: Run `cargo test` and `cargo clippy` 4. **Commit**: Follow git commit message conventions (enforced by `git_hooks/commit-msg`) 5. **Push**: Push branch to submit PR via ngit ## Resources - **Main Repository**: [gitworkshop.dev/dan@gitworkshop.dev/ngit](https://gitworkshop.dev/dan@gitworkshop.dev/ngit) - **Homepage**: [gitworkshop.dev/ngit](https://gitworkshop.dev/ngit) - **Source**: [codeberg.org/DanConwayDev/ngit-cli](https://codeberg.org/DanConwayDev/ngit-cli) - **Nostr Protocol**: [github.com/nostr-protocol/nostr](https://github.com/nostr-protocol/nostr) ## Quick Reference ### Build Commands ```bash cargo build # Development build cargo build --release # Release build cargo test # Run tests cargo clippy # Run linter cargo fmt # Format code ``` ### File Locations ```bash src/lib/repo_ref.rs # URL handling, grasp server detection src/lib/client.rs # Nostr client src/lib/git_events.rs # Git event handling src/bin/ngit/main.rs # Main CLI entry point src/bin/git_remote_nostr/ # Git remote helper tests/ # Integration tests ``` ### Key Functions ```rust // URL handling is_grasp_server_in_list(url, list) // Check if URL in list (exact match) is_grasp_server_clone_url(url) // Check if URL is grasp server format normalize_grasp_server_url(url) // Extract server part from URL // Repository operations repo_ref.to_nostr_git_url() // Convert to nostr URL push_to_remote() // Push to git server fetch_from_remote() // Fetch from git server ``` ## Support and Questions For questions about the codebase or contributions: - Check existing issues on [gitworkshop.dev](https://gitworkshop.dev/dan@gitworkshop.dev/ngit) - Review test files for usage examples - Examine integration tests for workflow examples --- **Last Updated**: 2025-10-20 **Version**: 1.7.4 **Maintainer**: DanConwayDev