A CLI for tangled operations.
11
fork

Configure Feed

Select the types of activity you want to include in your feed.

Document tang workflows

onevcat 7fd0ccdd a30bf5f1

+335 -2
+335 -2
README.md
··· 1 1 # tang 2 2 3 - `tang` is a work-in-progress command-line client for Tangled. 3 + `tang` is a command-line client for [Tangled](https://tangled.org/). 4 + It is designed for day-to-day repository work from a terminal: checking your 5 + Tangled identity, managing SSH keys, finding the current repository, listing and 6 + creating issues, and working with pull requests. 7 + 8 + The tool talks to Tangled through its AT Protocol data model: 9 + 10 + - Authentication is performed against the user's PDS. 11 + - Issues, pull requests, comments, status records, and SSH keys are stored as 12 + ATProto records. 13 + - Repository and pull request operations use the Tangled AppView, Constellation, 14 + and knot APIs as needed. 15 + 16 + ## Status 17 + 18 + This project is usable for the implemented workflows, but still early. The 19 + current command set covers: 20 + 21 + - `auth`: login, logout, token refresh, token inspection, auth status. 22 + - `status`: combined auth, repository, and service status. 23 + - `config`: local configuration for knot, AppView, Constellation, and preferred 24 + git remote. 25 + - `ssh-key`: list, add, and delete Tangled SSH public keys. 26 + - `repo`: view, list, create, and clone repositories. 27 + - `issue`: list, create, view, edit, comment, close, and reopen issues. 28 + - `pr`: list, create, view, diff, comment, checkout, close, reopen, and merge 29 + pull requests. 30 + - `browse`: open Tangled pages from the current repository context. 31 + - `completion`: generate shell completions. 32 + 33 + Some Tangled server-side behavior is eventually consistent. After creating, 34 + closing, reopening, or commenting on records, AppView and Constellation results 35 + may take a short time to reflect the latest state. 36 + 37 + ## Installation 38 + 39 + Build a local binary: 40 + 41 + ```sh 42 + make build 43 + ./bin/tang --help 44 + ``` 45 + 46 + Install into your Go binary path: 47 + 48 + ```sh 49 + make install 50 + tang --help 51 + ``` 52 + 53 + The module currently targets Go 1.25. 54 + 55 + ## First-Time Setup 56 + 57 + Log in with a Tangled handle and app password: 58 + 59 + ```sh 60 + tang auth login --handle alice.example 61 + ``` 62 + 63 + The command prompts for the app password. Session credentials are stored through 64 + the operating system keyring when available. The PDS URL is resolved from the 65 + handle's DID document; `pds.url` is intentionally not a persistent config key. 66 + 67 + Check the session: 68 + 69 + ```sh 70 + tang auth status 71 + tang auth refresh 72 + tang auth token --json 73 + ``` 74 + 75 + Manage SSH keys: 76 + 77 + ```sh 78 + tang ssh-key list 79 + tang ssh-key add ~/.ssh/id_ed25519.pub 80 + tang ssh-key delete <key-rkey> 81 + ``` 82 + 83 + Use `ssh-key list --json` when you need stable record identifiers for deletion 84 + or automation. 85 + 86 + ## Repository Context 87 + 88 + Most repository-scoped commands can infer the target repository from the current 89 + git worktree. `tang` scans git remotes and selects a Tangled remote using this 90 + order: 91 + 92 + 1. The configured preferred remote from `tang config set remote <name>`. 93 + 2. `origin`, when it is a Tangled remote. 94 + 3. The first Tangled remote found. 95 + 96 + Supported repository selectors include: 97 + 98 + ```sh 99 + tang status 100 + tang repo view 101 + tang issue list 102 + tang pr list 103 + ``` 104 + 105 + You can override the inferred repository with `-R`: 106 + 107 + ```sh 108 + tang issue list -R onev.cat/tang 109 + tang pr view 1 -R tangled.org/core 110 + ``` 111 + 112 + The selector format is `[HOST/]OWNER/REPO`. If no host is provided, configured 113 + knot hosts are used. 114 + 115 + ## Core Workflows 116 + 117 + ### Inspect Your Environment 118 + 119 + ```sh 120 + tang status 121 + tang status --section auth 122 + tang status --section repo 123 + tang config list 124 + ``` 125 + 126 + Use JSON output for scripts: 127 + 128 + ```sh 129 + tang status --json 130 + tang status --json=auth,repository 131 + tang repo view --json=name,knot,uri 132 + ``` 133 + 134 + `--json` without a value prints all fields. `--json=a,b,c` prints only selected 135 + fields. 136 + 137 + ### Work With Repositories 138 + 139 + View the current repository: 140 + 141 + ```sh 142 + tang repo view 143 + ``` 144 + 145 + List repositories for an owner: 146 + 147 + ```sh 148 + tang repo list onev.cat 149 + ``` 150 + 151 + Clone a repository: 152 + 153 + ```sh 154 + tang repo clone onev.cat/tang-playground 155 + tang repo clone onev.cat/tang-playground ./playground 156 + ``` 157 + 158 + Create a repository: 159 + 160 + ```sh 161 + tang repo create my-tool --description "A small Tangled tool" --knot knot1.tangled.sh 162 + ``` 163 + 164 + Repository creation depends on the selected knot. If the default AppView does 165 + not expose a create-capable route, pass an explicit `--knot`. 166 + 167 + ### Work With Issues 168 + 169 + List issues: 170 + 171 + ```sh 172 + tang issue list 173 + tang issue list --state all 174 + tang issue list --state closed --limit 20 175 + ``` 176 + 177 + Create an issue: 178 + 179 + ```sh 180 + tang issue create "Fix repository context detection" --body "Remote parsing misses push URLs." 181 + ``` 182 + 183 + Read a body from a file or stdin: 4 184 5 - The project is not yet usable for day-to-day workflows. The initial milestones build toward auth, repository, issue, pull request, SSH key, status, config, browse, and completion commands. 185 + ```sh 186 + tang issue create "Document release process" --body-file ./issue.md 187 + printf 'Body from stdin\n' | tang issue create "CLI polish" --body-file - 188 + ``` 189 + 190 + View, comment, edit, and change state: 191 + 192 + ```sh 193 + tang issue view 1 194 + tang issue view 1 --web 195 + tang issue comment 1 --body "Confirmed on main." 196 + tang issue edit 1 --title "Fix remote context detection" 197 + tang issue close 1 198 + tang issue reopen 1 199 + ``` 200 + 201 + Issue arguments may be a displayed number such as `1` or `#1`, a record rkey, or 202 + a full AT URI. 203 + 204 + ### Work With Pull Requests 205 + 206 + List and inspect pull requests: 207 + 208 + ```sh 209 + tang pr list 210 + tang pr list --state all 211 + tang pr view 1 212 + tang pr view 1 --web 213 + tang pr diff 1 214 + ``` 215 + 216 + Create a pull request from a pushed branch: 217 + 218 + ```sh 219 + git push origin my-branch 220 + tang pr create --base main --head my-branch --title "Add repository docs" --body-file ./pr.md 221 + ``` 222 + 223 + When the patch contains a mail-style subject, `--fill` can derive the title: 224 + 225 + ```sh 226 + tang pr create --base main --head my-branch --fill 227 + ``` 228 + 229 + Review and update a pull request: 230 + 231 + ```sh 232 + tang pr comment 1 --body "Looks good after the latest patch." 233 + tang pr checkout 1 234 + tang pr close 1 235 + tang pr reopen 1 236 + ``` 237 + 238 + Merge a pull request: 239 + 240 + ```sh 241 + tang pr merge 1 --subject "Merge pull request #1" 242 + ``` 243 + 244 + `pr merge` applies the pull request patch locally, commits it, and records the 245 + pull request as merged on Tangled. Review the worktree before and after merging, 246 + especially when the pull request contains a large patch. 247 + 248 + Pull request arguments may be a displayed number such as `1` or `#1`, a record 249 + rkey, or a full AT URI. 250 + 251 + ### Open Tangled In A Browser 252 + 253 + Open the current repository page: 254 + 255 + ```sh 256 + tang browse 257 + ``` 258 + 259 + Open an issue: 260 + 261 + ```sh 262 + tang browse issue 1 263 + ``` 264 + 265 + ### Configure Services 266 + 267 + Configuration is stored under the user config directory as `tang/config.toml` 268 + for the current platform. 269 + 270 + Common settings: 271 + 272 + ```sh 273 + tang config list 274 + tang config get knot.hosts 275 + tang config set knot.hosts tangled.org,knot1.tangled.sh 276 + tang config set appview.url https://tangled.org 277 + tang config set constellation.url https://constellation.microcosm.blue 278 + tang config set remote origin 279 + ``` 280 + 281 + `TANG_CONSTELLATION_URL` overrides `constellation.url` at runtime. This is useful 282 + for testing against a local or staging Constellation instance. 283 + 284 + ## Global Flags 285 + 286 + All commands support: 287 + 288 + ```text 289 + --json[=fields] Output JSON, optionally filtered by comma-separated fields. 290 + --pds URL Override PDS URL for auth and testing. 291 + -R, --repo REPO Select another repository using [HOST/]OWNER/REPO. 292 + ``` 293 + 294 + Use `--pds` for tests and diagnostics. Normal login and write workflows should 295 + let `tang` resolve the PDS from the active identity. 296 + 297 + ## Shell Completion 298 + 299 + Generate shell completion scripts: 300 + 301 + ```sh 302 + tang completion zsh 303 + tang completion bash 304 + tang completion fish 305 + tang completion powershell 306 + ``` 6 307 7 308 ## Development 8 309 310 + Useful commands: 311 + 9 312 ```sh 10 313 make test 314 + make lint 11 315 make build 12 316 ./bin/tang --help 13 317 ``` 318 + 319 + The main implementation areas are: 320 + 321 + - `cmd/tang`: binary entry point. 322 + - `internal/cli`: Cobra command wiring and user-facing behavior. 323 + - `internal/auth`: session and keyring handling. 324 + - `internal/config`: TOML config loading and supported keys. 325 + - `internal/git`: git remote parsing. 326 + - `internal/repo`: repository context resolution. 327 + - `internal/tangled`: Tangled AppView, PDS, knot, issue, repository, and pull 328 + request clients. 329 + - `internal/constellation`: Constellation API client. 330 + 331 + Before changing behavior, prefer adding focused tests near the package that owns 332 + the logic. For command behavior, use `internal/cli` tests. For record parsing, 333 + resolution, and API mapping, use `internal/tangled`, `internal/git`, or 334 + `internal/repo` tests. 335 + 336 + ## Known Limitations 337 + 338 + - Tangled AppView and Constellation indexing may lag behind successful PDS 339 + writes. 340 + - Some older pull request records do not contain patch rounds, so `pr diff` and 341 + `pr checkout` cannot operate on them. 342 + - `repo create` requires a create-capable knot. Pass `--knot` when the default 343 + service route is not sufficient. 344 + - `pr merge` is intentionally local-git based. It applies the patch and creates 345 + a commit in the current worktree, so the caller remains responsible for 346 + reviewing and pushing the result.