ngit 2.2.0

nostr plugin for git
Documentation
# 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://<npub|nip05-address>/<identifier>`

## 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://<npub|nip05>/<identifier>`
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