It's Super Bowl Sunday. I'm at a friend's house, beer in hand, half-watching the pregame. Between conversations I pull out my phone and text my AI agent:
"go for it"
Three words. By the end of the night, I have a fully-typed, zero-dependency TypeScript SoundCloud client published to npm — with 100% test coverage, a CLI tool, OAuth 2.1 with PKCE, automatic retry, TypeDoc site, CI/CD pipeline, and provenance-signed releases.
I didn't write most of it at a desk. I wrote it from a couch, between plays, reviewing pull requests on my phone and texting back "looks good, ship it."
This is the story of how that happened.
The code nobody was supposed to see
I've been building The Sub Delta — a music discovery app — on and off since 2015. It's powered by the SoundCloud API. Over the years I'd accumulated about 24 API functions, a handful of raw types, some mappers, and a bunch of https.request calls glued together with vibes and optimism.
It worked. It was also the kind of code you keep in a private repo and hope nobody asks about. Hardcoded credentials in env files, inconsistent error handling, no tests, no docs, types named things like SCApiTrack that only made sense to me.
I'd always thought about cleaning it up and open-sourcing it. But "cleaning up" a messy internal library into something you'd put your name on? That's a weekend project that somehow never happens.
Then I got an AI agent.
Meet Twin Paws
I run OpenClaw — an open-source platform that lets you run AI agents as long-lived daemons on your machine. My agent's name is Twin Paws. It runs Claude Opus 4.6 under the hood on a $600 Mac Mini sitting on my desk — with its own user account, its own GitHub, its own npm credentials. It doesn't have access to any of my personal accounts or files. It has its own filesystem, terminal, browser, and git — and I can talk to it over iMessage.
That last part is the key. I don't need to be at my computer. I don't need to open a terminal. I text Twin Paws like I'd text a coworker, and it handles the rest.
So on Saturday — the day before the Super Bowl — I texted:
"I want to take my SoundCloud API code and turn it into a standalone npm package. Zero dependencies, fully typed, professional quality. Something anyone could use."
And Twin Paws got to work.
The hypervelocity part
Here's what happened over the next 36 hours, most of which I was not sitting at a computer:
Saturday afternoon — Twin Paws analyzed my monorepo, identified all 24 SoundCloud API functions, 7 raw types, 15 normalized types, and 8 mappers. It proposed an extraction plan and a class-based SoundCloudClient architecture with namespaced methods (sc.tracks.getTrack(id) instead of getTrack(token, id)).
I reviewed the plan on my phone. Texted back some tweaks. It started building.
Saturday evening — The initial package was scaffolded at /tsd-soundcloud/. All TSD-specific code stripped. Types renamed from internal shorthand (SCApiUser) to public-facing names (SoundCloudUser). OAuth flow implemented with PKCE support. Auto-refresh on 401. Typed errors with SoundCloudError. Exponential backoff on rate limits.
I was making dinner. Checked my phone between stirring pasta. "Looks good, keep going."
Saturday night — Before bed, I texted Twin Paws something I'd never tried before:
"Do something that would surprise me while I sleep."
I had no idea what it would come up with. I figured maybe better docs, or some extra tests. I went to sleep.
Super Bowl Sunday morning — I woke up to a message: Twin Paws had built an entire interactive CLI tool (sc-cli) from scratch. Search tracks from your terminal. Stream URLs. OAuth login flow. JSON output for scripting. It decided, completely on its own, that the package needed a CLI — and just built one. That was a genuinely fun thing to wake up to.
Super Bowl Sunday, pregame — Twin Paws had also audited against the SoundCloud OpenAPI spec and added ~20 new endpoints I'd never implemented. It wrote 249 tests. Set up CI/CD with GitHub Actions. Created a TypeDoc site. Added llms.txt and AGENTS.md so other AI agents could understand the package. Pushed the first version to npm.
I was eating chips and salsa and chicken wings at my friend's house. I'd glance at my phone, see a message from Twin Paws: "v1.4.0 published. 94.7% statement coverage. 6 lint warnings remaining — want me to fix?"
"Yeah fix em."
During the game — Coverage went from 94% to 100%. README expanded with comparison tables against competitors. Pre-commit hooks for secret scanning. Migration PR opened against my monorepo. Credentials scrubbed from git history.
Meanwhile, I was watching the Seahawks crush the Patriots. I've lived in the Seattle area and finally made the Seahawks my team this year — and man, did I pick a good year. (Yes, I know, I know — in before the bandwagon comments. Sometimes timing is just taste.)
Between the second and third quarter, I texted "add a comparison with soundcloud.ts and soundcloud-fetch — real packages, not hypothetical." Twenty minutes later I had a detailed competitive analysis showing we're 4.5KB vs their 191KB (or outright unbundlable due to a 70MB ffmpeg binary dependency).
After the game — I'm driving home. I get a text: "v1.8.2 published. 262 tests, 100% line and function coverage. Dynamic badges, bundle size comparison, pnpm standardized, CHANGELOG rebuilt."
By the time I walked in my front door, the package was more polished than things I've spent weeks on manually.
What we actually built
Enough story — here's what came out the other side:
npm install soundcloud-api-ts
import { SoundCloudClient } from "soundcloud-api-ts";
const sc = new SoundCloudClient({
clientId: "your-client-id",
clientSecret: "your-client-secret",
redirectUri: "https://yourapp.com/callback",
});
const token = await sc.auth.getClientToken();
sc.setToken(token.access_token);
const results = await sc.search.tracks("lofi beats");
const track = await sc.tracks.getTrack(123456);
const streams = await sc.tracks.getStreams(123456);
The numbers
-
4.5 KB min+gzip (zero dependencies, native
fetch) - 262 tests, 100% line and function coverage
- OAuth 2.1 + PKCE — the only SoundCloud package using the official auth flow
- Automatic retry with exponential backoff on 429/5xx
-
Typed errors —
SoundCloudErrorwith status, code, body -
Async pagination —
fetchAll()andpaginate()with iterators -
Interactive CLI —
sc-cli search "lofi"right from your terminal (the agent's idea, not mine) -
Dual ESM/CJS with full
.d.tsdeclarations - Provenance-signed via npm Trusted Publishing (no tokens, pure OIDC)
vs the competition
| soundcloud-api-ts | soundcloud.ts | soundcloud-fetch | |
|---|---|---|---|
| Bundle size | 4.5 KB | ❌ unbundlable (70MB native binary) | 191 KB |
| Dependencies | 0 | 1 (ffmpeg-static) | 3 (lodash, cookie, undici) |
| Auth | Official OAuth 2.1 | ⚠️ Scrapes client ID | ⚠️ Scrapes client ID |
| API | Official api.soundcloud.com
|
Undocumented api-v2
|
Undocumented api-v2
|
| PKCE | ✅ | ❌ | ❌ |
| Auto retry | ✅ | ❌ | ❌ |
| CLI | ✅ | ❌ | ❌ |
| Coverage | 100% | — | — |
The existing packages scrape a client ID from SoundCloud's web frontend and hit their undocumented internal API. This breaks when SoundCloud redesigns (it has, repeatedly) and may violate their Terms of Use. We use the official registered-app OAuth flow. No scraping. No undocumented endpoints.
The CLI
sc-cli auth # Set up credentials
sc-cli search "lofi" # Search tracks
sc-cli track 293 # Track details
sc-cli stream 293 # Get stream URLs
sc-cli login # OAuth login
sc-cli me # Your profile
sc-cli likes # Your liked tracks
Every command supports --json for scripting.
What this is really about
This isn't a story about a SoundCloud package. It's about what happens when you can delegate real engineering work to an AI agent and steer it from your phone.
I didn't "vibe code" this in the pejorative sense — I wasn't blindly accepting AI output and praying. I reviewed every meaningful decision. I pushed back on architecture choices. I caught a credentials leak before it hit GitHub. The agent proposed, I disposed.
But the velocity was something I've never experienced. Things that would've taken me a full weekend of focused work — writing 262 tests, building a CLI (which, again, was entirely the agent's idea), setting up CI/CD, writing migration guides, competitive analysis — happened in the background while I lived my life.
The pattern was:
- I describe what I want in plain English (via text message)
- Twin Paws does the work (code, tests, docs, deploys)
- I review on my phone and steer ("looks good" / "change this" / "that's wrong")
- Repeat
Or sometimes: I say "surprise me" and wake up to a fully-built CLI tool.
I spent maybe 2-3 hours of actual attention on this across the weekend. The agent logged probably 15+ hours of work. And the output quality? I'd stack this package against anything I've built manually.
The uncomfortable realization
Here's the thing nobody talks about in the "AI coding" discourse: the bottleneck isn't code generation. It's taste. Knowing what to build, what the API should feel like, what tradeoffs to make, when to push back on the agent's suggestions.
The agent can write 262 tests. It can't decide that using the official OAuth API is more important than scraping a client ID for convenience. It can't decide that zero dependencies is a feature worth optimizing for. It can't decide that sc.tracks.getTrack(id) is a better API than getTrack(token, id).
Those decisions took me 30 seconds each, on my phone, between bites of chicken wings while watching the Seahawks put up another touchdown (or should I say field goal). The implementation of each one took the agent 20 minutes. That's the leverage.
Try it
npm install soundcloud-api-ts
- 📦 npm
- 🐙 GitHub
- 📖 API Docs
- 🔀 Migration Guide (coming from soundcloud.ts)
If you're using the SoundCloud API in TypeScript, give it a shot. If you're using soundcloud.ts, the migration takes 10 minutes and drops 70MB of native binary from your deps.
And if you want to try the "text your agent from the couch" workflow — OpenClaw is open source. Fair warning: your productivity might get weird.
Built with OpenClaw + Claude Opus 4.6. Shipped from a couch. ⚡
Top comments (0)