@rocksky/cli 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +270 -1
  2. package/TOOLS.md +194 -0
  3. package/bun.lock +28 -0
  4. package/dist/drizzle/0000_parallel_paper_doll.sql +220 -0
  5. package/dist/drizzle/meta/0000_snapshot.json +1559 -0
  6. package/dist/drizzle/meta/_journal.json +13 -0
  7. package/dist/index.js +8718 -165
  8. package/drizzle/0000_parallel_paper_doll.sql +220 -0
  9. package/drizzle/meta/0000_snapshot.json +1559 -0
  10. package/drizzle/meta/_journal.json +13 -0
  11. package/drizzle.config.ts +18 -0
  12. package/package.json +34 -4
  13. package/src/client.ts +32 -14
  14. package/src/cmd/mcp.ts +8 -0
  15. package/src/cmd/scrobble-api.ts +457 -0
  16. package/src/cmd/scrobble.ts +14 -61
  17. package/src/cmd/search.ts +27 -25
  18. package/src/cmd/sync.ts +812 -0
  19. package/src/cmd/whoami.ts +36 -7
  20. package/src/context.ts +24 -0
  21. package/src/drizzle.ts +53 -0
  22. package/src/index.ts +72 -23
  23. package/src/jetstream.ts +285 -0
  24. package/src/lexicon/index.ts +1321 -0
  25. package/src/lexicon/lexicons.ts +5453 -0
  26. package/src/lexicon/types/app/bsky/actor/profile.ts +38 -0
  27. package/src/lexicon/types/app/rocksky/actor/defs.ts +146 -0
  28. package/src/lexicon/types/app/rocksky/actor/getActorAlbums.ts +56 -0
  29. package/src/lexicon/types/app/rocksky/actor/getActorArtists.ts +56 -0
  30. package/src/lexicon/types/app/rocksky/actor/getActorCompatibility.ts +48 -0
  31. package/src/lexicon/types/app/rocksky/actor/getActorLovedSongs.ts +52 -0
  32. package/src/lexicon/types/app/rocksky/actor/getActorNeighbours.ts +48 -0
  33. package/src/lexicon/types/app/rocksky/actor/getActorPlaylists.ts +52 -0
  34. package/src/lexicon/types/app/rocksky/actor/getActorScrobbles.ts +52 -0
  35. package/src/lexicon/types/app/rocksky/actor/getActorSongs.ts +56 -0
  36. package/src/lexicon/types/app/rocksky/actor/getProfile.ts +43 -0
  37. package/src/lexicon/types/app/rocksky/album/defs.ts +85 -0
  38. package/src/lexicon/types/app/rocksky/album/getAlbum.ts +43 -0
  39. package/src/lexicon/types/app/rocksky/album/getAlbumTracks.ts +48 -0
  40. package/src/lexicon/types/app/rocksky/album/getAlbums.ts +50 -0
  41. package/src/lexicon/types/app/rocksky/album.ts +51 -0
  42. package/src/lexicon/types/app/rocksky/apikey/createApikey.ts +51 -0
  43. package/src/lexicon/types/app/rocksky/apikey/defs.ts +31 -0
  44. package/src/lexicon/types/app/rocksky/apikey/getApikeys.ts +50 -0
  45. package/src/lexicon/types/app/rocksky/apikey/removeApikey.ts +43 -0
  46. package/src/lexicon/types/app/rocksky/apikey/updateApikey.ts +53 -0
  47. package/src/lexicon/types/app/rocksky/apikeys/defs.ts +7 -0
  48. package/src/lexicon/types/app/rocksky/artist/defs.ts +140 -0
  49. package/src/lexicon/types/app/rocksky/artist/getArtist.ts +43 -0
  50. package/src/lexicon/types/app/rocksky/artist/getArtistAlbums.ts +48 -0
  51. package/src/lexicon/types/app/rocksky/artist/getArtistListeners.ts +52 -0
  52. package/src/lexicon/types/app/rocksky/artist/getArtistTracks.ts +52 -0
  53. package/src/lexicon/types/app/rocksky/artist/getArtists.ts +52 -0
  54. package/src/lexicon/types/app/rocksky/artist.ts +41 -0
  55. package/src/lexicon/types/app/rocksky/charts/defs.ts +44 -0
  56. package/src/lexicon/types/app/rocksky/charts/getScrobblesChart.ts +49 -0
  57. package/src/lexicon/types/app/rocksky/dropbox/defs.ts +71 -0
  58. package/src/lexicon/types/app/rocksky/dropbox/downloadFile.ts +42 -0
  59. package/src/lexicon/types/app/rocksky/dropbox/getFiles.ts +43 -0
  60. package/src/lexicon/types/app/rocksky/dropbox/getMetadata.ts +43 -0
  61. package/src/lexicon/types/app/rocksky/dropbox/getTemporaryLink.ts +43 -0
  62. package/src/lexicon/types/app/rocksky/feed/defs.ts +182 -0
  63. package/src/lexicon/types/app/rocksky/feed/describeFeedGenerator.ts +48 -0
  64. package/src/lexicon/types/app/rocksky/feed/generator.ts +29 -0
  65. package/src/lexicon/types/app/rocksky/feed/getFeed.ts +47 -0
  66. package/src/lexicon/types/app/rocksky/feed/getFeedGenerator.ts +48 -0
  67. package/src/lexicon/types/app/rocksky/feed/getFeedGenerators.ts +43 -0
  68. package/src/lexicon/types/app/rocksky/feed/getFeedSkeleton.ts +56 -0
  69. package/src/lexicon/types/app/rocksky/feed/getNowPlayings.ts +43 -0
  70. package/src/lexicon/types/app/rocksky/feed/search.ts +43 -0
  71. package/src/lexicon/types/app/rocksky/googledrive/defs.ts +42 -0
  72. package/src/lexicon/types/app/rocksky/googledrive/downloadFile.ts +42 -0
  73. package/src/lexicon/types/app/rocksky/googledrive/getFile.ts +43 -0
  74. package/src/lexicon/types/app/rocksky/googledrive/getFiles.ts +43 -0
  75. package/src/lexicon/types/app/rocksky/graph/defs.ts +47 -0
  76. package/src/lexicon/types/app/rocksky/graph/follow.ts +28 -0
  77. package/src/lexicon/types/app/rocksky/graph/followAccount.ts +50 -0
  78. package/src/lexicon/types/app/rocksky/graph/getFollowers.ts +56 -0
  79. package/src/lexicon/types/app/rocksky/graph/getFollows.ts +56 -0
  80. package/src/lexicon/types/app/rocksky/graph/getKnownFollowers.ts +52 -0
  81. package/src/lexicon/types/app/rocksky/graph/unfollowAccount.ts +50 -0
  82. package/src/lexicon/types/app/rocksky/like/dislikeShout.ts +49 -0
  83. package/src/lexicon/types/app/rocksky/like/dislikeSong.ts +49 -0
  84. package/src/lexicon/types/app/rocksky/like/likeShout.ts +49 -0
  85. package/src/lexicon/types/app/rocksky/like/likeSong.ts +49 -0
  86. package/src/lexicon/types/app/rocksky/like.ts +27 -0
  87. package/src/lexicon/types/app/rocksky/player/addDirectoryToQueue.ts +40 -0
  88. package/src/lexicon/types/app/rocksky/player/addItemsToQueue.ts +39 -0
  89. package/src/lexicon/types/app/rocksky/player/defs.ts +57 -0
  90. package/src/lexicon/types/app/rocksky/player/getCurrentlyPlaying.ts +44 -0
  91. package/src/lexicon/types/app/rocksky/player/getPlaybackQueue.ts +42 -0
  92. package/src/lexicon/types/app/rocksky/player/next.ts +34 -0
  93. package/src/lexicon/types/app/rocksky/player/pause.ts +34 -0
  94. package/src/lexicon/types/app/rocksky/player/play.ts +34 -0
  95. package/src/lexicon/types/app/rocksky/player/playDirectory.ts +38 -0
  96. package/src/lexicon/types/app/rocksky/player/playFile.ts +35 -0
  97. package/src/lexicon/types/app/rocksky/player/previous.ts +34 -0
  98. package/src/lexicon/types/app/rocksky/player/seek.ts +36 -0
  99. package/src/lexicon/types/app/rocksky/playlist/createPlaylist.ts +37 -0
  100. package/src/lexicon/types/app/rocksky/playlist/defs.ts +86 -0
  101. package/src/lexicon/types/app/rocksky/playlist/getPlaylist.ts +43 -0
  102. package/src/lexicon/types/app/rocksky/playlist/getPlaylists.ts +50 -0
  103. package/src/lexicon/types/app/rocksky/playlist/insertDirectory.ts +39 -0
  104. package/src/lexicon/types/app/rocksky/playlist/insertFiles.ts +38 -0
  105. package/src/lexicon/types/app/rocksky/playlist/removePlaylist.ts +35 -0
  106. package/src/lexicon/types/app/rocksky/playlist/removeTrack.ts +37 -0
  107. package/src/lexicon/types/app/rocksky/playlist/startPlaylist.ts +39 -0
  108. package/src/lexicon/types/app/rocksky/playlist.ts +43 -0
  109. package/src/lexicon/types/app/rocksky/radio/defs.ts +63 -0
  110. package/src/lexicon/types/app/rocksky/radio.ts +37 -0
  111. package/src/lexicon/types/app/rocksky/scrobble/createScrobble.ts +91 -0
  112. package/src/lexicon/types/app/rocksky/scrobble/defs.ts +93 -0
  113. package/src/lexicon/types/app/rocksky/scrobble/getScrobble.ts +43 -0
  114. package/src/lexicon/types/app/rocksky/scrobble/getScrobbles.ts +54 -0
  115. package/src/lexicon/types/app/rocksky/scrobble.ts +75 -0
  116. package/src/lexicon/types/app/rocksky/shout/createShout.ts +49 -0
  117. package/src/lexicon/types/app/rocksky/shout/defs.ts +58 -0
  118. package/src/lexicon/types/app/rocksky/shout/getAlbumShouts.ts +52 -0
  119. package/src/lexicon/types/app/rocksky/shout/getArtistShouts.ts +52 -0
  120. package/src/lexicon/types/app/rocksky/shout/getProfileShouts.ts +52 -0
  121. package/src/lexicon/types/app/rocksky/shout/getShoutReplies.ts +52 -0
  122. package/src/lexicon/types/app/rocksky/shout/getTrackShouts.ts +48 -0
  123. package/src/lexicon/types/app/rocksky/shout/removeShout.ts +43 -0
  124. package/src/lexicon/types/app/rocksky/shout/replyShout.ts +51 -0
  125. package/src/lexicon/types/app/rocksky/shout/reportShout.ts +51 -0
  126. package/src/lexicon/types/app/rocksky/shout.ts +30 -0
  127. package/src/lexicon/types/app/rocksky/song/createSong.ts +71 -0
  128. package/src/lexicon/types/app/rocksky/song/defs.ts +103 -0
  129. package/src/lexicon/types/app/rocksky/song/getSong.ts +43 -0
  130. package/src/lexicon/types/app/rocksky/song/getSongs.ts +50 -0
  131. package/src/lexicon/types/app/rocksky/song.ts +74 -0
  132. package/src/lexicon/types/app/rocksky/spotify/defs.ts +35 -0
  133. package/src/lexicon/types/app/rocksky/spotify/getCurrentlyPlaying.ts +43 -0
  134. package/src/lexicon/types/app/rocksky/spotify/next.ts +32 -0
  135. package/src/lexicon/types/app/rocksky/spotify/pause.ts +32 -0
  136. package/src/lexicon/types/app/rocksky/spotify/play.ts +32 -0
  137. package/src/lexicon/types/app/rocksky/spotify/previous.ts +32 -0
  138. package/src/lexicon/types/app/rocksky/spotify/seek.ts +35 -0
  139. package/src/lexicon/types/app/rocksky/stats/defs.ts +33 -0
  140. package/src/lexicon/types/app/rocksky/stats/getStats.ts +43 -0
  141. package/src/lexicon/types/com/atproto/repo/strongRef.ts +26 -0
  142. package/src/lexicon/util.ts +13 -0
  143. package/src/lib/agent.ts +56 -0
  144. package/src/lib/cleanUpJetstreamLock.ts +66 -0
  145. package/src/lib/cleanUpSyncLock.ts +56 -0
  146. package/src/lib/didUnstorageCache.ts +72 -0
  147. package/src/lib/env.ts +25 -0
  148. package/src/lib/extractPdsFromDid.ts +33 -0
  149. package/src/lib/getDidAndHandle.ts +39 -0
  150. package/src/lib/idResolver.ts +52 -0
  151. package/src/lib/lastfm.ts +26 -0
  152. package/src/lib/matchTrack.ts +47 -0
  153. package/src/logger.ts +18 -0
  154. package/src/mcp/index.ts +269 -0
  155. package/src/mcp/tools/albums.ts +13 -0
  156. package/src/mcp/tools/artists.ts +17 -0
  157. package/src/mcp/tools/create.ts +27 -0
  158. package/src/mcp/tools/myscrobbles.ts +42 -0
  159. package/src/mcp/tools/nowplaying.ts +53 -0
  160. package/src/mcp/tools/scrobbles.ts +39 -0
  161. package/src/mcp/tools/search.ts +88 -0
  162. package/src/mcp/tools/stats.ts +40 -0
  163. package/src/mcp/tools/tracks.ts +15 -0
  164. package/src/mcp/tools/whoami.ts +27 -0
  165. package/src/schema/album-tracks.ts +30 -0
  166. package/src/schema/albums.ts +29 -0
  167. package/src/schema/artist-albums.ts +29 -0
  168. package/src/schema/artist-genres.ts +17 -0
  169. package/src/schema/artist-tracks.ts +29 -0
  170. package/src/schema/artists.ts +30 -0
  171. package/src/schema/auth-session.ts +18 -0
  172. package/src/schema/genres.ts +18 -0
  173. package/src/schema/index.ts +33 -0
  174. package/src/schema/loved-tracks.ts +27 -0
  175. package/src/schema/scrobbles.ts +30 -0
  176. package/src/schema/tracks.ts +39 -0
  177. package/src/schema/user-albums.ts +31 -0
  178. package/src/schema/user-artists.ts +32 -0
  179. package/src/schema/user-tracks.ts +31 -0
  180. package/src/schema/users.ts +21 -0
  181. package/src/scrobble.ts +410 -0
  182. package/src/sqliteKv.ts +173 -0
  183. package/src/types.ts +308 -0
  184. package/tsconfig.json +26 -29
@@ -1,69 +1,22 @@
1
- import chalk from "chalk";
2
- import { RockskyClient } from "client";
3
- import fs from "fs/promises";
4
- import md5 from "md5";
5
- import os from "os";
6
- import path from "path";
1
+ import { matchTrack } from "lib/matchTrack";
2
+ import { publishScrobble } from "scrobble";
7
3
 
8
- export async function scrobble(track, artist, { timestamp }) {
9
- const tokenPath = path.join(os.homedir(), ".rocksky", "token.json");
10
- try {
11
- await fs.access(tokenPath);
12
- } catch (err) {
13
- console.error(
14
- `You are not logged in. Please run ${chalk.greenBright(
15
- "`rocksky login <username>.bsky.social`"
16
- )} first.`
17
- );
18
- return;
19
- }
4
+ export async function scrobble(
5
+ track: string,
6
+ artist: string,
7
+ { timestamp, dryRun },
8
+ ) {
9
+ const match = await matchTrack(track, artist);
20
10
 
21
- const tokenData = await fs.readFile(tokenPath, "utf-8");
22
- const { token } = JSON.parse(tokenData);
23
- if (!token) {
24
- console.error(
25
- `You are not logged in. Please run ${chalk.greenBright(
26
- "`rocksky login <username>.bsky.social`"
27
- )} first.`
28
- );
29
- return;
11
+ if (!match) {
12
+ process.exit(1);
30
13
  }
31
14
 
32
- const client = new RockskyClient(token);
33
- const apikeys = await client.getApiKeys();
15
+ const success = await publishScrobble(match, timestamp, dryRun);
34
16
 
35
- if (!apikeys || apikeys.length === 0 || !apikeys[0].enabled) {
36
- console.error(
37
- `You don't have any API keys. Please create one using ${chalk.greenBright(
38
- "`rocksky create apikey`"
39
- )} command.`
40
- );
41
- return;
17
+ if (!success) {
18
+ process.exit(1);
42
19
  }
43
20
 
44
- const signature = md5(
45
- `api_key${
46
- apikeys[0].apiKey
47
- }artist[0]${artist}methodtrack.scrobblesk${token}timestamp[0]${
48
- timestamp || Math.floor(Date.now() / 1000)
49
- }track[0]${track}${apikeys[0].sharedSecret}`
50
- );
51
-
52
- const response = await client.scrobble(
53
- apikeys[0].apiKey,
54
- signature,
55
- track,
56
- artist,
57
- timestamp
58
- );
59
-
60
- console.log(
61
- `Scrobbled ${chalk.greenBright(track)} by ${chalk.greenBright(
62
- artist
63
- )} at ${chalk.greenBright(
64
- new Date(
65
- (timestamp || Math.floor(Date.now() / 1000)) * 1000
66
- ).toLocaleString()
67
- )}`
68
- );
21
+ process.exit(0);
69
22
  }
package/src/cmd/search.ts CHANGED
@@ -1,71 +1,73 @@
1
1
  import chalk from "chalk";
2
2
  import { RockskyClient } from "client";
3
+ import _ from "lodash";
3
4
 
4
5
  export async function search(
5
6
  query: string,
6
- { limit = 20, albums = false, artists = false, tracks = false, users = false }
7
+ {
8
+ limit = 20,
9
+ albums = false,
10
+ artists = false,
11
+ tracks = false,
12
+ users = false,
13
+ },
7
14
  ) {
8
15
  const client = new RockskyClient();
9
16
  const results = await client.search(query, { size: limit });
10
- if (results.records.length === 0) {
17
+ if (results.hits.length === 0) {
11
18
  console.log(`No results found for ${chalk.magenta(query)}.`);
12
19
  return;
13
20
  }
14
21
 
15
- // merge all results into one array with type and sort by xata_scrore
16
- let mergedResults = results.records.map((record) => ({
22
+ let mergedResults = results.hits.map((record) => ({
17
23
  ...record,
18
- type: record.table,
24
+ type: _.get(record, "_federation.indexUid"),
19
25
  }));
20
26
 
21
27
  if (albums) {
22
- mergedResults = mergedResults.filter((record) => record.table === "albums");
28
+ mergedResults = mergedResults.filter((record) => record.type === "albums");
23
29
  }
24
30
 
25
31
  if (artists) {
26
- mergedResults = mergedResults.filter(
27
- (record) => record.table === "artists"
28
- );
32
+ mergedResults = mergedResults.filter((record) => record.type === "artists");
29
33
  }
30
34
 
31
35
  if (tracks) {
32
- mergedResults = mergedResults.filter(({ table }) => table === "tracks");
36
+ mergedResults = mergedResults.filter(({ type }) => type === "tracks");
33
37
  }
34
38
 
35
39
  if (users) {
36
- mergedResults = mergedResults.filter(({ table }) => table === "users");
40
+ mergedResults = mergedResults.filter(({ type }) => type === "users");
37
41
  }
38
42
 
39
- mergedResults.sort((a, b) => b.xata_score - a.xata_score);
40
-
41
- for (const { table, record } of mergedResults) {
42
- if (table === "users") {
43
+ for (const { type, ...record } of mergedResults) {
44
+ if (type === "users") {
43
45
  console.log(
44
46
  `${chalk.bold.magenta(record.handle)} ${
45
- record.display_name
46
- } ${chalk.yellow(`https://rocksky.app/profile/${record.did}`)}`
47
+ record.displayName
48
+ } ${chalk.yellow(`https://rocksky.app/profile/${record.did}`)}`,
47
49
  );
48
50
  }
49
51
 
50
- if (table === "albums") {
52
+ if (type === "albums") {
51
53
  const link = record.uri
52
- ? `https://rocksky.app/${record.uri?.split("at://")[1]}`
54
+ ? `https://rocksky.app/${record.uri?.split("at://")[1]?.replace("app.rocksky.", "")}`
53
55
  : "";
54
56
  console.log(
55
57
  `${chalk.bold.magenta(record.title)} ${record.artist} ${chalk.yellow(
56
- link
57
- )}`
58
+ link,
59
+ )}`,
58
60
  );
59
61
  }
60
62
 
61
- if (table === "tracks") {
63
+ if (type === "tracks") {
62
64
  const link = record.uri
63
- ? `https://rocksky.app/${record.uri?.split("at://")[1]}`
65
+ ? `https://rocksky.app/${record.uri?.split("at://")[1]?.replace("app.rocksky.", "")}`
64
66
  : "";
65
67
  console.log(
66
68
  `${chalk.bold.magenta(record.title)} ${record.artist} ${chalk.yellow(
67
- link
68
- )}`
69
+ link,
70
+ )}`,
69
71
  );
70
72
  }
71
73
  }