🎧 The official command-line interface for Rocksky — a modern, decentralized music tracking and discovery platform built on the AT Protocol.
1#!/usr/bin/env node
2
3import { albums } from "cmd/albums";
4import { artists } from "cmd/artists";
5import { createApiKey } from "cmd/create";
6import { nowplaying } from "cmd/nowplaying";
7import { scrobble } from "cmd/scrobble";
8import { scrobbles } from "cmd/scrobbles";
9import { search } from "cmd/search";
10import { stats } from "cmd/stats";
11import { tracks } from "cmd/tracks";
12import { whoami } from "cmd/whoami";
13import { Command } from "commander";
14import version from "../package.json" assert { type: "json" };
15import { login } from "./cmd/login";
16
17const program = new Command();
18
19program
20 .name("rocksky")
21 .description(
22 "Command-line interface for Rocksky – scrobble tracks, view stats, and manage your listening history."
23 )
24 .version(version.version);
25
26program
27 .command("login")
28 .argument("<handle>", "your BlueSky handle (e.g., <username>.bsky.social)")
29 .description("login with your BlueSky account and get a session token.")
30 .action(login);
31
32program
33 .command("whoami")
34 .description("get the current logged-in user.")
35 .action(whoami);
36
37program
38 .command("nowplaying")
39 .argument(
40 "[did]",
41 "the DID or handle of the user to get the now playing track for."
42 )
43 .description("get the currently playing track.")
44 .action(nowplaying);
45
46program
47 .command("scrobbles")
48 .option("-s, --skip <number>", "number of scrobbles to skip")
49 .option("-l, --limit <number>", "number of scrobbles to limit")
50 .argument("[did]", "the DID or handle of the user to get the scrobbles for.")
51 .description("display recently played tracks.")
52 .action(scrobbles);
53
54program
55 .command("search")
56 .option("-a, --albums", "search for albums")
57 .option("-t, --tracks", "search for tracks")
58 .option("-u, --users", "search for users")
59 .option("-l, --limit <number>", "number of results to limit")
60 .argument(
61 "<query>",
62 "the search query, e.g., artist, album, title or account"
63 )
64 .description("search for tracks, albums, or accounts.")
65 .action(search);
66
67program
68 .command("stats")
69 .option("-l, --limit <number>", "number of results to limit")
70 .argument("[did]", "the DID or handle of the user to get stats for.")
71 .description("get the user's listening stats.")
72 .action(stats);
73
74program
75 .command("artists")
76 .option("-l, --limit <number>", "number of results to limit")
77 .argument("[did]", "the DID or handle of the user to get artists for.")
78 .description("get the user's top artists.")
79 .action(artists);
80
81program
82 .command("albums")
83 .option("-l, --limit <number>", "number of results to limit")
84 .argument("[did]", "the DID or handle of the user to get albums for.")
85 .description("get the user's top albums.")
86 .action(albums);
87
88program
89 .command("tracks")
90 .option("-l, --limit <number>", "number of results to limit")
91 .argument("[did]", "the DID or handle of the user to get tracks for.")
92 .description("get the user's top tracks.")
93 .action(tracks);
94
95program
96 .command("scrobble")
97 .argument("<track>", "the title of the track")
98 .argument("<artist>", "the artist of the track")
99 .option("-t, --timestamp <timestamp>", "the timestamp of the scrobble")
100 .description("scrobble a track to your profile.")
101 .action(scrobble);
102
103program
104 .command("create")
105 .description("create a new API key.")
106 .command("apikey")
107 .argument("<name>", "the name of the API key")
108 .option("-d, --description <description>", "the description of the API key")
109 .description("create a new API key.")
110 .action(createApiKey);
111
112program.parse(process.argv);