1# Tangled CLI – Current Implementation Status 2 3This document provides an overview of the Tangled CLI implementation status for AI agents or developers working on the project. 4 5## Implementation Status 6 7### ✅ Fully Implemented 8 9#### Authentication (`auth`) 10- `login` - Authenticate with AT Protocol using `com.atproto.server.createSession` 11- `status` - Show current authentication status 12- `logout` - Clear stored session from keyring 13 14#### Repositories (`repo`) 15- `list` - List repositories using `com.atproto.repo.listRecords` with `collection=sh.tangled.repo` 16- `create` - Create repositories with two-step flow: 17 1. Create PDS record via `com.atproto.repo.createRecord` 18 2. Initialize bare repo via `sh.tangled.repo.create` with ServiceAuth 19- `clone` - Clone repositories using libgit2 with SSH agent support 20- `info` - Display repository information including stats and languages 21- `delete` - Delete repositories (both PDS record and knot repo) 22- `star` / `unstar` - Star/unstar repositories via `sh.tangled.feed.star` 23 24#### Issues (`issue`) 25- `list` - List issues via `com.atproto.repo.listRecords` with `collection=sh.tangled.repo.issue` 26- `create` - Create issues via `com.atproto.repo.createRecord` 27- `show` - Show issue details and comments 28- `edit` - Edit issue title, body, or state 29- `comment` - Add comments to issues 30 31#### Pull Requests (`pr`) 32- `list` - List PRs via `com.atproto.repo.listRecords` with `collection=sh.tangled.repo.pull` 33- `create` - Create PRs using `git format-patch` for patches 34- `show` - Show PR details and diff 35- `review` - Review PRs with approve/request-changes flags 36- `merge` - Merge PRs via `sh.tangled.repo.merge` with ServiceAuth 37 38#### Knot Management (`knot`) 39- `migrate` - Migrate repositories between knots 40 - Validates working tree is clean and pushed 41 - Creates new repo on target knot with source seeding 42 - Updates PDS record to point to new knot 43 44#### Spindle CI/CD (`spindle`) 45- `config` - Enable/disable or configure spindle URL for a repository 46 - Updates the `spindle` field in `sh.tangled.repo` record 47- `list` - List pipeline runs via `com.atproto.repo.listRecords` with `collection=sh.tangled.pipeline` 48- `logs` - Stream workflow logs via WebSocket (`wss://spindle.tangled.sh/spindle/logs/{knot}/{rkey}/{name}`) 49- `secret list` - List secrets via `sh.tangled.repo.listSecrets` with ServiceAuth 50- `secret add` - Add secrets via `sh.tangled.repo.addSecret` with ServiceAuth 51- `secret remove` - Remove secrets via `sh.tangled.repo.removeSecret` with ServiceAuth 52 53### 🚧 Partially Implemented / Stubs 54 55#### Spindle CI/CD (`spindle`) 56- `run` - Manually trigger a workflow (stub) 57 - **TODO**: Parse `.tangled.yml` to determine workflows 58 - **TODO**: Create pipeline record and trigger spindle ingestion 59 - **TODO**: Support manual trigger inputs 60 61## Architecture Overview 62 63### Workspace Structure 64 65- `crates/tangled-cli` - CLI binary with clap-based argument parsing 66- `crates/tangled-config` - Configuration and keyring-backed session management 67- `crates/tangled-api` - XRPC client wrapper for AT Protocol and Tangled APIs 68- `crates/tangled-git` - Git operation helpers (currently unused) 69 70### Key Patterns 71 72#### ServiceAuth Flow 73Many Tangled API operations require ServiceAuth tokens: 741. Obtain token via `com.atproto.server.getServiceAuth` from PDS 75 - `aud` parameter must be `did:web:<target-host>` 76 - `exp` parameter should be Unix timestamp + 600 seconds 772. Use token as `Authorization: Bearer <serviceAuth>` for Tangled API calls 78 79#### Repository Creation Flow 80Two-step process: 811. **PDS**: Create `sh.tangled.repo` record via `com.atproto.repo.createRecord` 822. **Tangled API**: Initialize bare repo via `sh.tangled.repo.create` with ServiceAuth 83 84#### Repository Listing 85Done entirely via PDS (not Tangled API): 861. Resolve handle → DID if needed via `com.atproto.identity.resolveHandle` 872. List records via `com.atproto.repo.listRecords` with `collection=sh.tangled.repo` 883. Filter client-side (e.g., by knot) 89 90#### Pull Request Merging 911. Fetch PR record to get patch and target branch 922. Obtain ServiceAuth token 933. Call `sh.tangled.repo.merge` with `{did, name, patch, branch, commitMessage, commitBody}` 94 95### Base URLs and Defaults 96 97- **PDS Base** (auth + record operations): Default `https://bsky.social`, stored in session 98- **Tangled API Base** (server operations): Default `https://tngl.sh`, can override via `TANGLED_API_BASE` 99- **Spindle Base** (CI/CD): Default `wss://spindle.tangled.sh` for WebSocket logs, can override via `TANGLED_SPINDLE_BASE` 100 101### Session Management 102 103Sessions are stored in the system keyring: 104- Linux: GNOME Keyring / KWallet via Secret Service API 105- macOS: macOS Keychain 106- Windows: Windows Credential Manager 107 108Session includes: 109```rust 110struct Session { 111 access_jwt: String, 112 refresh_jwt: String, 113 did: String, 114 handle: String, 115 pds: Option<String>, // PDS base URL 116} 117``` 118 119## Working with tangled-core 120 121The `../tangled-core` repository contains the server implementation and lexicon definitions. 122 123### Key Files to Check 124 125- **Lexicons**: `../tangled-core/lexicons/**/*.json` 126 - Defines XRPC method schemas (NSIDs, parameters, responses) 127 - Example: `sh.tangled.repo.create`, `sh.tangled.repo.merge` 128 129- **XRPC Routes**: `../tangled-core/knotserver/xrpc/xrpc.go` 130 - Shows which endpoints require ServiceAuth 131 - Maps NSIDs to handler functions 132 133- **API Handlers**: `../tangled-core/knotserver/xrpc/*.go` 134 - Implementation details for server-side operations 135 - Example: `create_repo.go`, `merge.go` 136 137### Useful Search Commands 138 139```bash 140# Find a specific NSID 141rg -n "sh\.tangled\.repo\.create" ../tangled-core 142 143# List all lexicons 144ls ../tangled-core/lexicons/repo 145 146# Check ServiceAuth usage 147rg -n "ServiceAuth|VerifyServiceAuth" ../tangled-core 148``` 149 150## Next Steps for Contributors 151 152### Priority: Implement `spindle run` 153 154The only remaining stub is `spindle run` for manually triggering workflows. Implementation plan: 155 1561. **Parse `.tangled.yml`** in the current repository to extract workflow definitions 157 - Look for workflow names, triggers, and manual trigger inputs 158 1592. **Create pipeline record** on PDS via `com.atproto.repo.createRecord`: 160 ```rust 161 collection: "sh.tangled.pipeline" 162 record: { 163 triggerMetadata: { 164 kind: "manual", 165 repo: { knot, did, repo, defaultBranch }, 166 manual: { inputs: [...] } 167 }, 168 workflows: [{ name, engine, clone, raw }] 169 } 170 ``` 171 1723. **Notify spindle** (if needed) or let the ingester pick up the new record 173 1744. **Support workflow selection** when multiple workflows exist: 175 - `--workflow <name>` flag to select specific workflow 176 - Default to first workflow if not specified 177 1785. **Support manual inputs** (if workflow defines them): 179 - Prompt for input values or accept via flags 180 181### Code Quality Tasks 182 183- Add more comprehensive error messages for common failure cases 184- Improve table formatting for list commands (consider using `tabled` crate features) 185- Add shell completion generation (bash, zsh, fish) 186- Add more unit tests with `mockito` for API client methods 187- Add integration tests with `assert_cmd` for CLI commands 188 189### Documentation Tasks 190 191- Add man pages for all commands 192- Create video tutorials for common workflows 193- Add troubleshooting guide for common issues 194 195## Development Workflow 196 197### Building 198 199```sh 200cargo build # Debug build 201cargo build --release # Release build 202``` 203 204### Running 205 206```sh 207cargo run -p tangled-cli -- <command> 208``` 209 210### Testing 211 212```sh 213cargo test # Run all tests 214cargo test -- --nocapture # Show println output 215``` 216 217### Code Quality 218 219```sh 220cargo fmt # Format code 221cargo clippy # Run linter 222cargo clippy -- -W clippy::all # Strict linting 223``` 224 225## Troubleshooting Common Issues 226 227### Keyring Errors on Linux 228 229Ensure a secret service is running: 230```sh 231systemctl --user enable --now gnome-keyring-daemon 232``` 233 234### Invalid Token Errors 235 236- For record operations: Use PDS client, not Tangled API client 237- For server operations: Ensure ServiceAuth audience DID matches target host 238 239### Repository Not Found 240 241- Verify repo exists: `tangled repo info owner/name` 242- Check you're using the correct owner (handle or DID) 243- Ensure you have access permissions 244 245### WebSocket Connection Failures 246 247- Check spindle base URL is correct (default: `wss://spindle.tangled.sh`) 248- Verify the job_id format: `knot:rkey:name` 249- Ensure the workflow has actually run and has logs 250 251## Additional Resources 252 253- Main README: `README.md` - User-facing documentation 254- Getting Started Guide: `docs/getting-started.md` - Tutorial for new users 255- Lexicons: `../tangled-core/lexicons/` - XRPC method definitions 256- Server Implementation: `../tangled-core/knotserver/` - Server-side code 257 258--- 259 260Last updated: 2025-10-14