audio streaming app plyr.fm
38
fork

Configure Feed

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

docs: update STATUS.md — SDK namespace restructure, playlist support, cyclopts CLI (#1294)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

authored by

nate nowack
Claude Opus 4.6 (1M context)
and committed by
GitHub
05fb1219 118ab6b4

+21 -1
+21 -1
STATUS.md
··· 47 47 48 48 ### April 2026 49 49 50 + #### SDK namespace restructure + playlist support (plyr-python-client v0.0.1a16, PR #1293, Apr 13) 51 + 52 + **why**: the [plyr-python-client](https://github.com/zzstoatzz/plyr-python-client) SDK, MCP server, and CLI had grown organically as flat methods/commands. the SDK had 17 flat methods on `PlyrClient` (`client.list_tracks()`, `client.like(42)`), the CLI had inconsistent naming (`delete` for tracks but `delete-playlist` for playlists, `tags electronic` returning tracks), and there was no playlist support at all despite the backend having 12 playlist endpoints. a gap analysis ([#24](https://github.com/zzstoatzz/plyr-python-client/issues/24)) identified albums, playlists, artists, discovery, and platform state as uncovered. 53 + 54 + **what shipped** ([plyr-python-client#30](https://github.com/zzstoatzz/plyr-python-client/pull/30)): 55 + - **SDK namespace restructure** — flat methods → namespace objects following the OpenAI/Stripe SDK pattern: `client.tracks.list()`, `client.playlists.create()`, `client.discover.search()`, `client.tags.tracks("ambient")`. both sync (`PlyrClient`) and async (`AsyncPlyrClient`) clients have identical namespace APIs, verified by parity tests 56 + - **proper identifier types** — `TrackRef = TrackId | TrackUri` using `Annotated[..., Field(description=...)]`. every track-targeting method accepts either a plyr.fm integer ID or an ATProto URI (`at://did/collection/rkey`), resolved internally. the SDK fetches the track via `/tracks/by-uri` when given a URI, then uses the integer ID for mutation endpoints that require it 57 + - **playlist CRUD** — 9 new SDK methods: `list`, `get`, `create`, `update`, `delete`, `add_track`, `remove_track`, `recommendations`, `by_artist`. `add_track` and `remove_track` accept `TrackRef` and resolve to the ATProto URI/CID needed by the backend's list record operations 58 + - **cyclopts CLI** — migrated from hand-rolled `sys.argv` parsing to [cyclopts](https://cyclopts.readthedocs.io/) with noun-first subcommands: `plyrfm tracks list`, `plyrfm playlists create`, `plyrfm discover search`, `plyrfm tags list`. cyclopts was chosen over click/typer for its `Annotated`-native parameter config, native `int | str` union support (needed for `TrackRef`), and docstring-based help generation 59 + - **MCP server** — updated to use namespace API internally; flat tool names preserved (appropriate for MCP protocol). 4 new read-only playlist tools: `list_playlists`, `get_playlist`, `playlists_by_artist`, `playlist_recommendations` 60 + 61 + **decisions**: 62 + - SDK namespaces over flat methods: the namespace pattern (`client.tracks.*`, `client.playlists.*`) groups related operations and prevents naming collisions as the API surface grows (e.g. `tracks.list()` vs `playlists.list()`). the alternative — prefixed flat methods (`list_tracks`, `list_playlists`, `list_albums`) — scales poorly 63 + - `TrackRef` accepts both ID and URI because the SDK serves two audiences: plyr.fm developers (who think in integer IDs) and ATProto ecosystem users (who think in AT-URIs from PDSLS). the SDK resolves internally so neither audience needs to convert 64 + - cyclopts over click: cyclopts uses `Annotated[type, Parameter(...)]` instead of decorators, so command functions remain callable in tests without the framework. it also handles `int | str` unions natively (tries each type left-to-right), which click cannot do 65 + - MCP tool names stayed flat: MCP tools are discovered by name in a flat list — noun-verb namespacing doesn't add value there 66 + - this is a breaking change (flat methods → namespaces, CLI restructure) but the SDK is at `v0.0.1-alpha` so this is expected. the plyr.fm repo's workflow scripts and `llms-full.txt` were updated in #1293 67 + 68 + --- 69 + 50 70 #### avatar restore on account reactivation (PR #1291, Apr 13) 51 71 52 72 **why**: a user deactivated their ATProto account and then reactivated it. their avatar disappeared from plyr.fm during deactivation (the `cdn.bsky.app` URL went dead) and never came back — the jetstream consumer ignored `kind=account` events entirely, and `ingest_identity_update` only refreshed handle + PDS URL, not the avatar. ··· 508 528 509 529 --- 510 530 511 - this is a living document. last updated 2026-04-11 (CDN caching via custom domains, backend API decomposition, PDS URL healing, scripts cleanup). 531 + this is a living document. last updated 2026-04-13 (SDK namespace restructure, playlist support, cyclopts CLI migration). 512 532