Udpate AGENTS.md

Changed files
+78
+78
AGENTS.md
··· 361 361 362 362 End of handoff. Implement auth login and repo list as described, keeping changes focused and testable. 363 363 364 + 365 + -------------------------------------------------------------------------------- 366 + 367 + ## 13) Tangled Core (../tangled-core) – Practical Notes 368 + 369 + This workspace often needs to peek at the Tangled monorepo to confirm XRPC endpoints and shapes. Here are concise tips and findings that informed this CLI implementation. 370 + 371 + ### Where To Look 372 + 373 + - Lexicons (authoritative NSIDs and shapes): `../tangled-core/lexicons/**` 374 + - Repo create: `../tangled-core/lexicons/repo/create.json` → `sh.tangled.repo.create` 375 + - Repo record schema: `../tangled-core/lexicons/repo/repo.json` → `sh.tangled.repo` 376 + - Misc repo queries (tree, log, tags, etc.) under `../tangled-core/lexicons/repo/` 377 + - Note: there is no `sh.tangled.repo.list` lexicon in the core right now; listing is done via ATproto records. 378 + - Knotserver XRPC routes (what requires auth vs open): `../tangled-core/knotserver/xrpc/xrpc.go` 379 + - Mutating repo ops (e.g., `sh.tangled.repo.create`) are behind ServiceAuth middleware. 380 + - Read-only repo queries (tree, log, etc.) are open. 381 + - Create repo handler (server-side flow): `../tangled-core/knotserver/xrpc/create_repo.go` 382 + - Validates ServiceAuth; expects rkey for the `sh.tangled.repo` record that already exists on the user's PDS. 383 + - ServiceAuth middleware (how Bearer is validated): `../tangled-core/xrpc/serviceauth/service_auth.go` 384 + - Validates a ServiceAuth token with Audience = `did:web:<knot-or-service-host>`. 385 + - Appview client for ServiceAuth: `../tangled-core/appview/xrpcclient/xrpc.go` (method: `ServerGetServiceAuth`). 386 + 387 + ### How To Search Quickly (rg examples) 388 + 389 + - Find a specific NSID across the repo: 390 + - `rg -n "sh\.tangled\.repo\.create" ../tangled-core` 391 + - See which endpoints are routed and whether they’re behind ServiceAuth: 392 + - `rg -n "chi\..*Get\(|chi\..*Post\(" ../tangled-core/knotserver/xrpc` 393 + - Then open `xrpc.go` and respective handlers. 394 + - Discover ServiceAuth usage and audience DID: 395 + - `rg -n "ServerGetServiceAuth|VerifyServiceAuth|serviceauth" ../tangled-core` 396 + - List lexicons by area: 397 + - `ls ../tangled-core/lexicons/repo` or `rg -n "\bid\": \"sh\.tangled\..*\"" ../tangled-core/lexicons` 398 + 399 + ### Repo Listing (client-side pattern) 400 + 401 + - There is no `sh.tangled.repo.list` in core. To list a user’s repos: 402 + 1) Resolve handle → DID if needed via PDS: `GET com.atproto.identity.resolveHandle`. 403 + 2) List records from the user’s PDS: `GET com.atproto.repo.listRecords` with `collection=sh.tangled.repo`. 404 + 3) Filter client-side (e.g., by `knot`). “Starred” filtering is not currently defined in core. 405 + 406 + ### Repo Creation (two-step flow) 407 + 408 + - Step 1 (PDS): create the `sh.tangled.repo` record in the user’s repo: 409 + - `POST com.atproto.repo.createRecord` with `{ repo: <did>, collection: "sh.tangled.repo", record: { name, knot, description?, createdAt } }`. 410 + - Extract `rkey` from the returned `uri` (`at://<did>/<collection>/<rkey>`). 411 + - Step 2 (Tangled API base): call the server to initialize the bare repo on the knot: 412 + - Obtain ServiceAuth: `GET com.atproto.server.getServiceAuth` from PDS with `aud=did:web:<tngl.sh or target-host>`. 413 + - `POST sh.tangled.repo.create` on the Tangled API base with `{ rkey, defaultBranch?, source? }` and `Authorization: Bearer <serviceAuth>`. 414 + - Server validates token via `xrpc/serviceauth`, confirms actor permissions, and creates the git repo. 415 + 416 + ### Base URLs, DIDs, and Defaults 417 + 418 + - Tangled API base (server): default is `https://tngl.sh`. Do not use the marketing/landing site. 419 + - PDS base (auth + record ops): default `https://bsky.social` unless a different PDS was chosen on login. 420 + - ServiceAuth audience DID is `did:web:<host>` where `<host>` is the Tangled API base hostname. 421 + - CLI stores the PDS URL in the session to keep the CLI stateful. 422 + 423 + ### Common Errors and Fixes 424 + 425 + - `InvalidToken` when listing repos: listing should use the PDS (`com.atproto.repo.listRecords`), not the Tangled API base. 426 + - 404 on `repo.create`: verify ServiceAuth audience matches the target host and that the rkey exists on the PDS. 427 + - Keychain issues on Linux: ensure a Secret Service (e.g., GNOME Keyring or KWallet) is running. 428 + 429 + ### Implementation Pointers (CLI) 430 + 431 + - Auth 432 + - `com.atproto.server.createSession` against the PDS, save `{accessJwt, refreshJwt, did, handle, pds}` in keyring. 433 + - List repos 434 + - Use session.handle by default; resolve to DID, then `com.atproto.repo.listRecords` on PDS. 435 + - Create repo 436 + - Build the PDS record first; then ServiceAuth → `sh.tangled.repo.create` on `tngl.sh`. 437 + 438 + ### Testing Hints 439 + 440 + - Avoid live calls; use `mockito` to stub both PDS and Tangled API base endpoints. 441 + - Unit test decoding with minimal JSON envelopes: record lists, createRecord `uri`, and repo.create (empty body or simple ack).