@groovenet/cli 2.0.0 → 2.2.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.
package/README.md CHANGED
@@ -27,6 +27,7 @@ groovenet albums search "kind of blue" # browse albums
27
27
  groovenet playlists list # list playlists
28
28
  groovenet friends list # manage the friends system
29
29
  groovenet play <track-id> # play a track via MPD on the server
30
+ groovenet fingerprint-library # index reference audio for matching
30
31
  ```
31
32
 
32
33
  Every command accepts `--json` for machine-readable output:
@@ -46,6 +47,32 @@ Run `groovenet --help` (or `groovenet <command> --help`) for the full command re
46
47
  | `albums` | Browse and manage albums |
47
48
  | `playlists` | Manage playlists |
48
49
  | `friends` | Manage the friends system |
50
+ | `fingerprint-library` | Build the reference fingerprint index used to recognise vinyl as it plays |
51
+
52
+ ### fingerprint-library
53
+
54
+ Fingerprints the library's reference audio so live vinyl playback can be
55
+ recognised against it. Safe to re-run: each track's audio is hashed and skipped
56
+ when nothing has changed.
57
+
58
+ ```bash
59
+ groovenet fingerprint-library # only tracks not yet indexed
60
+ groovenet fingerprint-library --changed # re-check already-indexed files
61
+ groovenet fingerprint-library --all --force # regenerate everything
62
+ groovenet fingerprint-library --track 12345-1 # one track
63
+ groovenet fingerprint-library --release 12345 # one release
64
+ groovenet fingerprint-library --no-wait # queue it and return
65
+ ```
66
+
67
+ ```
68
+ Indexing missing — chromaprint 1
69
+ 3653 queued, 241 without reference audio
70
+ ✗ 12345-2: ffmpeg exited 1: Invalid data found when processing input
71
+ ✓ 3412 indexed ⤼ 0 skipped ✗ 2 failed – 241 no audio
72
+ ```
73
+
74
+ Tracks with no local audio are counted, not failed — only the part of the
75
+ library you have downloaded can be fingerprinted. Exits 1 if any track failed.
49
76
 
50
77
  ## Related
51
78
 
@@ -6,6 +6,8 @@ import { addTracksCommands } from "../commands/tracks.js";
6
6
  import { addAlbumsCommands } from "../commands/albums.js";
7
7
  import { addPlaylistsCommands } from "../commands/playlists.js";
8
8
  import { addFriendsCommands } from "../commands/friends.js";
9
+ import { addFingerprintLibraryCommand } from "../commands/fingerprintLibrary.js";
10
+ import { addVinylCommands } from "../commands/vinyl.js";
9
11
  const require = createRequire(import.meta.url);
10
12
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
11
13
  const { version } = require("../../package.json");
@@ -19,6 +21,8 @@ addTracksCommands(program);
19
21
  addAlbumsCommands(program);
20
22
  addPlaylistsCommands(program);
21
23
  addFriendsCommands(program);
24
+ addFingerprintLibraryCommand(program);
25
+ addVinylCommands(program);
22
26
  program.parseAsync(process.argv).catch((err) => {
23
27
  process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
24
28
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"groovenet.js","sourceRoot":"","sources":["../../src/bin/groovenet.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,sEAAsE;AACtE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE5B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC/D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"groovenet.js","sourceRoot":"","sources":["../../src/bin/groovenet.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,sEAAsE;AACtE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,4BAA4B,CAAC,OAAO,CAAC,CAAC;AACtC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC/D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"albums.d.ts","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwJxD"}
1
+ {"version":3,"file":"albums.d.ts","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmDpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwJxD"}
@@ -2,6 +2,7 @@ import { GroovenetClient, loadConfig } from "@groovenet/client";
2
2
  import Table from "cli-table3";
3
3
  import chalk from "chalk";
4
4
  import { printJson, printSuccess, printError, printTracks } from "../output.js";
5
+ import { intOption } from "../options.js";
5
6
  function makeClient() {
6
7
  const cfg = loadConfig();
7
8
  return new GroovenetClient({ baseUrl: cfg.api_base, apiKey: cfg.api_key, insecureTls: cfg.insecure_tls });
@@ -49,9 +50,9 @@ export function addAlbumsCommands(program) {
49
50
  .description("Search/list albums")
50
51
  .argument("[query]", "Search query", "")
51
52
  .option("--sort <s>", "Sort (created_at:desc, date_added:desc, year:desc, title:asc, album_rating:desc)", "created_at:desc")
52
- .option("--limit <n>", "Number of results", parseInt, 20)
53
- .option("--offset <n>", "Offset", parseInt, 0)
54
- .option("--friend-id <n>", "Friend ID", parseInt)
53
+ .option("--limit <n>", "Number of results", intOption, 20)
54
+ .option("--offset <n>", "Offset", intOption, 0)
55
+ .option("--friend-id <n>", "Friend ID", intOption)
55
56
  .option("--json", "Output as JSON")
56
57
  .action(async (query, opts) => {
57
58
  try {
@@ -82,7 +83,7 @@ export function addAlbumsCommands(program) {
82
83
  albums
83
84
  .command("show <release-id>")
84
85
  .description("Show album details and track list")
85
- .option("--friend-id <n>", "Friend ID", parseInt)
86
+ .option("--friend-id <n>", "Friend ID", intOption)
86
87
  .option("--json", "Output as JSON")
87
88
  .action(async (releaseId, opts) => {
88
89
  try {
@@ -123,7 +124,7 @@ export function addAlbumsCommands(program) {
123
124
  albums
124
125
  .command("update <release-id>")
125
126
  .description("Update album metadata")
126
- .option("--friend-id <n>", "Friend ID", parseInt)
127
+ .option("--friend-id <n>", "Friend ID", intOption)
127
128
  .option("--rating <n>", "Album rating (0-5)", parseFloat)
128
129
  .option("--notes <text>", "Album notes")
129
130
  .option("--price <n>", "Purchase price", parseFloat)
@@ -159,7 +160,7 @@ export function addAlbumsCommands(program) {
159
160
  albums
160
161
  .command("download <release-id>")
161
162
  .description("Queue all missing tracks in an album for download")
162
- .option("--friend-id <n>", "Friend ID", parseInt)
163
+ .option("--friend-id <n>", "Friend ID", intOption)
163
164
  .action(async (releaseId, opts) => {
164
165
  try {
165
166
  const client = makeClient();
@@ -1 +1 @@
1
- {"version":3,"file":"albums.js","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"albums.js","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { Command } from "commander";
2
+ import { GroovenetClient } from "@groovenet/client";
3
+ import type { FingerprintIndexRequest, FingerprintIndexRun } from "@groovenet/client";
4
+ export declare function makeClient(): GroovenetClient;
5
+ /** Just enough of the client for one run, so a test can pass two functions. */
6
+ export type FingerprintLibraryClient = Pick<GroovenetClient, "startFingerprintIndex" | "getFingerprintIndexRun">;
7
+ /**
8
+ * Where the command's output goes.
9
+ *
10
+ * Injected rather than reaching for `console` and `process.stdout` directly, so
11
+ * the whole run — header, per-failure lines, the rewritten progress line and
12
+ * the summary — can be asserted without a terminal.
13
+ */
14
+ export interface FingerprintLibraryIO {
15
+ /** A whole line, newline appended. */
16
+ log: (line: string) => void;
17
+ /** Raw, no newline — the progress line rewrites itself with \r. */
18
+ write: (text: string) => void;
19
+ }
20
+ export declare const consoleIO: FingerprintLibraryIO;
21
+ export interface FingerprintLibraryOptions {
22
+ missing?: boolean;
23
+ changed?: boolean;
24
+ all?: boolean;
25
+ track?: string;
26
+ release?: string;
27
+ friendId?: number;
28
+ force?: boolean;
29
+ wait?: boolean;
30
+ pollInterval?: number;
31
+ json?: boolean;
32
+ }
33
+ /**
34
+ * Turn the scope flags into one request.
35
+ *
36
+ * Exactly one scope, so `--missing --all` is refused rather than silently
37
+ * resolved to whichever the parser happened to see last. With no scope flag at
38
+ * all it is `--missing`: the cheap, common case, since the alternatives re-read
39
+ * and re-hash every already-indexed file.
40
+ */
41
+ export declare function resolveScope(opts: FingerprintLibraryOptions): FingerprintIndexRequest;
42
+ /** How many of the queued tracks have reached a terminal state. */
43
+ export declare function settledCount(run: FingerprintIndexRun): number;
44
+ /** `indexing 3412/3653 ██████████░░` — one line, rewritten in place. */
45
+ export declare function formatProgress(run: FingerprintIndexRun, width?: number): string;
46
+ /**
47
+ * The four counters the run reports.
48
+ *
49
+ * `unindexable` is listed apart from `failed` on purpose: a track with no
50
+ * `local_audio_url` has no reference audio to fingerprint, which is a fact
51
+ * about how much of the library has been downloaded, not a failure of the run.
52
+ */
53
+ export declare function formatSummary(run: FingerprintIndexRun): string;
54
+ /**
55
+ * Poll until every queued track has settled.
56
+ *
57
+ * `onProgress` is called with each poll so the caller owns the rendering — the
58
+ * loop itself stays testable without a terminal.
59
+ */
60
+ export declare function waitForRun(client: Pick<GroovenetClient, "getFingerprintIndexRun">, runId: string, opts: {
61
+ pollIntervalMs: number;
62
+ onProgress?: (run: FingerprintIndexRun) => void;
63
+ }): Promise<FingerprintIndexRun>;
64
+ /**
65
+ * One `fingerprint-library` run, start to finish. Returns the process exit
66
+ * code: non-zero when any track failed, so the command composes in a script.
67
+ *
68
+ * Separate from the commander wiring because everything interesting happens
69
+ * here — scope resolution, the two output modes, the polling and the exit code
70
+ * — and a commander action is not callable from a test.
71
+ */
72
+ export declare function runFingerprintLibrary(client: FingerprintLibraryClient, opts: FingerprintLibraryOptions, io?: FingerprintLibraryIO): Promise<number>;
73
+ export declare function addFingerprintLibraryCommand(program: Command): void;
74
+ //# sourceMappingURL=fingerprintLibrary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprintLibrary.d.ts","sourceRoot":"","sources":["../../src/commands/fingerprintLibrary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAc,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAKtF,wBAAgB,UAAU,IAAI,eAAe,CAO5C;AAED,+EAA+E;AAC/E,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,eAAe,EACf,uBAAuB,GAAG,wBAAwB,CACnD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,mEAAmE;IACnE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,SAAS,EAAE,oBAGvB,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,yBAAyB,GAC9B,uBAAuB,CAwBzB;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAE7D;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,KAAK,SAAK,GAAG,MAAM,CAM3E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAQ9D;AAMD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,EACvD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAA;CAAE,GAChF,OAAO,CAAC,mBAAmB,CAAC,CAO9B;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,wBAAwB,EAChC,IAAI,EAAE,yBAAyB,EAC/B,EAAE,GAAE,oBAAgC,GACnC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwBnE"}
@@ -0,0 +1,166 @@
1
+ import { GroovenetClient, loadConfig } from "@groovenet/client";
2
+ import chalk from "chalk";
3
+ import { printError } from "../output.js";
4
+ import { intOption } from "../options.js";
5
+ export function makeClient() {
6
+ const cfg = loadConfig();
7
+ return new GroovenetClient({
8
+ baseUrl: cfg.api_base,
9
+ apiKey: cfg.api_key,
10
+ insecureTls: cfg.insecure_tls,
11
+ });
12
+ }
13
+ export const consoleIO = {
14
+ log: (line) => console.log(line),
15
+ write: (text) => process.stdout.write(text),
16
+ };
17
+ /**
18
+ * Turn the scope flags into one request.
19
+ *
20
+ * Exactly one scope, so `--missing --all` is refused rather than silently
21
+ * resolved to whichever the parser happened to see last. With no scope flag at
22
+ * all it is `--missing`: the cheap, common case, since the alternatives re-read
23
+ * and re-hash every already-indexed file.
24
+ */
25
+ export function resolveScope(opts) {
26
+ const chosen = [
27
+ opts.missing ? "missing" : null,
28
+ opts.changed ? "changed" : null,
29
+ opts.all ? "all" : null,
30
+ opts.track ? "track" : null,
31
+ opts.release ? "release" : null,
32
+ ].filter((scope) => scope !== null);
33
+ if (chosen.length > 1) {
34
+ throw new Error(`Choose one scope, not ${chosen.length}: ${chosen.map((s) => `--${s}`).join(" ")}`);
35
+ }
36
+ const scope = (chosen[0] ?? "missing");
37
+ const request = { scope };
38
+ if (scope === "track")
39
+ request.track_id = opts.track;
40
+ if (scope === "release")
41
+ request.release_id = opts.release;
42
+ if (opts.friendId !== undefined)
43
+ request.friend_id = opts.friendId;
44
+ if (opts.force)
45
+ request.force = true;
46
+ return request;
47
+ }
48
+ /** How many of the queued tracks have reached a terminal state. */
49
+ export function settledCount(run) {
50
+ return run.indexed + run.skipped + run.failed;
51
+ }
52
+ /** `indexing 3412/3653 ██████████░░` — one line, rewritten in place. */
53
+ export function formatProgress(run, width = 24) {
54
+ const done = settledCount(run);
55
+ const ratio = run.queued > 0 ? Math.min(done / run.queued, 1) : 1;
56
+ const filled = Math.round(ratio * width);
57
+ const bar = "█".repeat(filled) + "░".repeat(width - filled);
58
+ return ` indexing ${done}/${run.queued} ${bar}`;
59
+ }
60
+ /**
61
+ * The four counters the run reports.
62
+ *
63
+ * `unindexable` is listed apart from `failed` on purpose: a track with no
64
+ * `local_audio_url` has no reference audio to fingerprint, which is a fact
65
+ * about how much of the library has been downloaded, not a failure of the run.
66
+ */
67
+ export function formatSummary(run) {
68
+ const parts = [
69
+ chalk.green(`✓ ${run.indexed} indexed`),
70
+ chalk.gray(`⤼ ${run.skipped} skipped`),
71
+ run.failed > 0 ? chalk.red(`✗ ${run.failed} failed`) : chalk.gray("✗ 0 failed"),
72
+ chalk.gray(`– ${run.unindexable} no audio`),
73
+ ];
74
+ return ` ${parts.join(" ")}`;
75
+ }
76
+ function sleep(ms) {
77
+ return new Promise((resolve) => setTimeout(resolve, ms));
78
+ }
79
+ /**
80
+ * Poll until every queued track has settled.
81
+ *
82
+ * `onProgress` is called with each poll so the caller owns the rendering — the
83
+ * loop itself stays testable without a terminal.
84
+ */
85
+ export async function waitForRun(client, runId, opts) {
86
+ for (;;) {
87
+ const run = await client.getFingerprintIndexRun(runId);
88
+ opts.onProgress?.(run);
89
+ if (run.complete)
90
+ return run;
91
+ await sleep(opts.pollIntervalMs);
92
+ }
93
+ }
94
+ /**
95
+ * One `fingerprint-library` run, start to finish. Returns the process exit
96
+ * code: non-zero when any track failed, so the command composes in a script.
97
+ *
98
+ * Separate from the commander wiring because everything interesting happens
99
+ * here — scope resolution, the two output modes, the polling and the exit code
100
+ * — and a commander action is not callable from a test.
101
+ */
102
+ export async function runFingerprintLibrary(client, opts, io = consoleIO) {
103
+ const request = resolveScope(opts);
104
+ const started = await client.startFingerprintIndex(request);
105
+ if (!opts.json) {
106
+ io.log(chalk.bold(`Indexing ${started.scope}`) +
107
+ chalk.gray(` — ${started.fingerprint_type} ${started.fingerprint_version}`));
108
+ io.log(chalk.gray(` ${started.queued} queued, ${started.unindexable} without reference audio`));
109
+ }
110
+ if (!opts.wait) {
111
+ if (opts.json)
112
+ io.write(JSON.stringify(started, null, 2) + "\n");
113
+ else
114
+ io.log(chalk.gray(` run ${started.run_id}`));
115
+ return 0;
116
+ }
117
+ const seen = new Set();
118
+ const finished = await waitForRun(client, started.run_id, {
119
+ pollIntervalMs: opts.pollInterval ?? 1000,
120
+ onProgress: (run) => {
121
+ if (opts.json)
122
+ return;
123
+ // Failures scroll above the progress line as they happen, so a long run
124
+ // does not hide them until the very end.
125
+ for (const failure of run.errors) {
126
+ if (seen.has(failure))
127
+ continue;
128
+ seen.add(failure);
129
+ io.log(chalk.red(` ✗ ${failure}`));
130
+ }
131
+ io.write(`\r${formatProgress(run)}`);
132
+ },
133
+ });
134
+ if (opts.json) {
135
+ io.write(JSON.stringify(finished, null, 2) + "\n");
136
+ return finished.failed > 0 ? 1 : 0;
137
+ }
138
+ io.write("\r\x1b[2K");
139
+ io.log(formatSummary(finished));
140
+ return finished.failed > 0 ? 1 : 0;
141
+ }
142
+ export function addFingerprintLibraryCommand(program) {
143
+ program
144
+ .command("fingerprint-library")
145
+ .description("Build the reference fingerprint index the live vinyl matcher searches")
146
+ .option("--missing", "Only tracks with no fingerprint yet (default)")
147
+ .option("--changed", "Only tracks already indexed, re-checked for edits")
148
+ .option("--all", "Every track with reference audio")
149
+ .option("--track <id>", "One track")
150
+ .option("--release <id>", "Every track on one release")
151
+ .option("--friend-id <n>", "Narrow to one friend's library", intOption)
152
+ .option("--force", "Re-fingerprint even when the audio is unchanged")
153
+ .option("--no-wait", "Queue the run and exit without waiting")
154
+ .option("--poll-interval <ms>", "How often to poll progress", intOption, 1000)
155
+ .option("--json", "Output as JSON")
156
+ .action(async (opts) => {
157
+ try {
158
+ process.exitCode = await runFingerprintLibrary(makeClient(), opts);
159
+ }
160
+ catch (err) {
161
+ printError(err instanceof Error ? err.message : String(err));
162
+ process.exit(1);
163
+ }
164
+ });
165
+ }
166
+ //# sourceMappingURL=fingerprintLibrary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprintLibrary.js","sourceRoot":"","sources":["../../src/commands/fingerprintLibrary.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tracks.d.ts","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuTxD"}
1
+ {"version":3,"file":"tracks.d.ts","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuTxD"}
@@ -1,6 +1,7 @@
1
1
  import { GroovenetClient, loadConfig } from "@groovenet/client";
2
2
  import { printTracks, printTrack, printJson, printSuccess, printError, } from "../output.js";
3
3
  import chalk from "chalk";
4
+ import { intOption } from "../options.js";
4
5
  function makeClient() {
5
6
  const cfg = loadConfig();
6
7
  return new GroovenetClient({ baseUrl: cfg.api_base, apiKey: cfg.api_key, insecureTls: cfg.insecure_tls });
@@ -14,7 +15,7 @@ export function addTracksCommands(program) {
14
15
  .option("--bpm-max <n>", "Maximum BPM", parseFloat)
15
16
  .option("--key <k>", "Musical key (e.g. 'A minor')")
16
17
  .option("--rating <n>", "Filter by star rating (0-5)", parseFloat)
17
- .option("--limit <n>", "Number of results", parseInt, 20)
18
+ .option("--limit <n>", "Number of results", intOption, 20)
18
19
  .option("--json", "Output as JSON")
19
20
  .action(async (query, opts) => {
20
21
  try {
@@ -52,7 +53,7 @@ export function addTracksCommands(program) {
52
53
  tracks
53
54
  .command("show <id>")
54
55
  .description("Show details for a track")
55
- .option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", parseInt)
56
+ .option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", intOption)
56
57
  .option("--json", "Output as JSON")
57
58
  .action(async (id, opts) => {
58
59
  try {
@@ -109,8 +110,8 @@ export function addTracksCommands(program) {
109
110
  tracks
110
111
  .command("missing-apple-music")
111
112
  .description("List tracks missing Apple Music URLs")
112
- .option("--page <n>", "Page number", parseInt, 1)
113
- .option("--page-size <n>", "Results per page", parseInt, 50)
113
+ .option("--page <n>", "Page number", intOption, 1)
114
+ .option("--page-size <n>", "Results per page", intOption, 50)
114
115
  .option("--username <u>", "Username")
115
116
  .option("--json", "Output as JSON")
116
117
  .action(async (opts) => {
@@ -133,9 +134,9 @@ export function addTracksCommands(program) {
133
134
  tracks
134
135
  .command("deleted")
135
136
  .description("List soft-deleted tracks")
136
- .option("--friend-id <n>", "Filter by friend ID", parseInt)
137
- .option("--limit <n>", "Max results", parseInt, 100)
138
- .option("--offset <n>", "Offset", parseInt, 0)
137
+ .option("--friend-id <n>", "Filter by friend ID", intOption)
138
+ .option("--limit <n>", "Max results", intOption, 100)
139
+ .option("--offset <n>", "Offset", intOption, 0)
139
140
  .option("--json", "Output as JSON")
140
141
  .action(async (opts) => {
141
142
  try {
@@ -160,7 +161,7 @@ export function addTracksCommands(program) {
160
161
  tracks
161
162
  .command("restore <id>")
162
163
  .description("Restore a soft-deleted track")
163
- .option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", parseInt)
164
+ .option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", intOption)
164
165
  .action(async (id, opts) => {
165
166
  try {
166
167
  const cfg = loadConfig();
@@ -177,7 +178,7 @@ export function addTracksCommands(program) {
177
178
  tracks
178
179
  .command("recommend <id>")
179
180
  .description("Get combined recommendations using both identity and audio vibe embeddings")
180
- .option("--limit <n>", "Number of candidates to return", parseInt, 20)
181
+ .option("--limit <n>", "Number of candidates to return", intOption, 20)
181
182
  .option("--json", "Output as JSON")
182
183
  .action(async (id, opts) => {
183
184
  try {
@@ -204,7 +205,7 @@ export function addTracksCommands(program) {
204
205
  tracks
205
206
  .command("similar-identity <id>")
206
207
  .description("Find tracks with similar identity (genre, era, style, tags)")
207
- .option("--limit <n>", "Number of results", parseInt, 10)
208
+ .option("--limit <n>", "Number of results", intOption, 10)
208
209
  .option("--era <era>", "Filter by era (e.g. '1970s')")
209
210
  .option("--country <country>", "Filter by country")
210
211
  .option("--tags <tags>", "Comma-separated tags to filter by")
@@ -235,7 +236,7 @@ export function addTracksCommands(program) {
235
236
  tracks
236
237
  .command("similar-vibe <id>")
237
238
  .description("Find tracks with similar audio vibe (BPM, mood, danceability)")
238
- .option("--limit <n>", "Number of results", parseInt, 10)
239
+ .option("--limit <n>", "Number of results", intOption, 10)
239
240
  .option("--json", "Output as JSON")
240
241
  .action(async (id, opts) => {
241
242
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"tracks.js","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracks.js","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Command } from "commander";
2
+ import { GroovenetClient } from "@groovenet/client";
3
+ import type { DetectionWindow, IngestPipelineStats } from "@groovenet/client";
4
+ export declare function makeClient(): GroovenetClient;
5
+ /** `47.2s` → `0:47`, which is how anyone thinks about a position in a track. */
6
+ export declare function formatOffset(seconds: number | null): string;
7
+ /**
8
+ * One window as a line.
9
+ *
10
+ * A no-match is rendered plainly rather than as an error: it is the expected
11
+ * state between tracks, and colouring it red would train you to ignore red.
12
+ */
13
+ export declare function formatDetection(d: DetectionWindow): string[];
14
+ /**
15
+ * The health summary.
16
+ *
17
+ * Leads with the index because an empty one is the failure that looks like
18
+ * success: chunks arrive, decode, and are reported `processed`, every one of
19
+ * them matching nothing.
20
+ */
21
+ export declare function formatStats(s: IngestPipelineStats): string;
22
+ export declare function addVinylCommands(program: Command): void;
23
+ //# sourceMappingURL=vinyl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vinyl.d.ts","sourceRoot":"","sources":["../../src/commands/vinyl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAc,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAM3B,wBAAgB,UAAU,IAAI,eAAe,CAO5C;AAOD,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAI3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAY5D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CA+D1D;AAoDD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0FvD"}
@@ -0,0 +1,229 @@
1
+ import { GroovenetClient, loadConfig } from "@groovenet/client";
2
+ import chalk from "chalk";
3
+ import Table from "cli-table3";
4
+ import { printJson, printError } from "../output.js";
5
+ import { intOption } from "../options.js";
6
+ export function makeClient() {
7
+ const cfg = loadConfig();
8
+ return new GroovenetClient({
9
+ baseUrl: cfg.api_base,
10
+ apiKey: cfg.api_key,
11
+ insecureTls: cfg.insecure_tls,
12
+ });
13
+ }
14
+ function clock(iso) {
15
+ if (!iso)
16
+ return "—";
17
+ return new Date(iso).toLocaleTimeString();
18
+ }
19
+ /** `47.2s` → `0:47`, which is how anyone thinks about a position in a track. */
20
+ export function formatOffset(seconds) {
21
+ if (seconds === null)
22
+ return "—";
23
+ const whole = Math.floor(seconds);
24
+ return `${Math.floor(whole / 60)}:${String(whole % 60).padStart(2, "0")}`;
25
+ }
26
+ /**
27
+ * One window as a line.
28
+ *
29
+ * A no-match is rendered plainly rather than as an error: it is the expected
30
+ * state between tracks, and colouring it red would train you to ignore red.
31
+ */
32
+ export function formatDetection(d) {
33
+ if (!d.matched) {
34
+ return [clock(d.window_start_at), chalk.gray("no match"), "—", "—"];
35
+ }
36
+ const confidence = d.confidence ?? 0;
37
+ const paint = confidence >= 0.85 ? chalk.green : chalk.yellow;
38
+ return [
39
+ clock(d.window_start_at),
40
+ `${d.artist ?? "?"} — ${d.title ?? "?"}`,
41
+ paint(confidence.toFixed(3)),
42
+ formatOffset(d.offset_seconds),
43
+ ];
44
+ }
45
+ /**
46
+ * The health summary.
47
+ *
48
+ * Leads with the index because an empty one is the failure that looks like
49
+ * success: chunks arrive, decode, and are reported `processed`, every one of
50
+ * them matching nothing.
51
+ */
52
+ export function formatStats(s) {
53
+ const lines = [];
54
+ if (!s.index.engine_registered) {
55
+ lines.push(chalk.red("✗ no fingerprint engine registered") +
56
+ chalk.gray(" — is fingerprint-service running?"));
57
+ }
58
+ else if (s.index.empty) {
59
+ lines.push(chalk.red("✗ reference index is EMPTY") +
60
+ chalk.gray(" — nothing can match; run `groovenet fingerprint-library`"));
61
+ }
62
+ else {
63
+ lines.push(chalk.green(`✓ index: ${s.index.indexed_tracks} tracks`) +
64
+ chalk.gray(` (${s.index.fingerprint_type} ${s.index.fingerprint_version})`));
65
+ }
66
+ const q = s.queue_depth;
67
+ lines.push(q === null
68
+ ? chalk.yellow("? queue depth unavailable (redis unreachable)")
69
+ : chalk.gray(` queue depth: ${q}`));
70
+ const st = s.ingests.by_status;
71
+ const counts = Object.entries(st)
72
+ .map(([k, v]) => `${k} ${v}`)
73
+ .join(" ");
74
+ lines.push(chalk.gray(` ingests (${s.window_minutes}m): ${counts || "none"}`));
75
+ for (const f of s.ingests.failures) {
76
+ lines.push(chalk.red(` ✗ ${f.count}× ${f.error}`));
77
+ }
78
+ const d = s.detections;
79
+ if (d.windows === 0) {
80
+ lines.push(chalk.gray(" detections: none in this window"));
81
+ }
82
+ else {
83
+ const rate = d.match_rate === null ? "—" : `${(d.match_rate * 100).toFixed(1)}%`;
84
+ lines.push(chalk.gray(` detections: ${d.windows} windows, ${d.matched} matched, ` +
85
+ `${d.no_match} no-match (${rate})`));
86
+ for (const b of d.confidence_bands) {
87
+ lines.push(chalk.gray(` ${b.band} ${b.count}`));
88
+ }
89
+ }
90
+ if (s.ingests.oldest_in_flight) {
91
+ const o = s.ingests.oldest_in_flight;
92
+ lines.push(chalk.yellow(` oldest in flight: ${o.status} since ${clock(o.received_at)}`));
93
+ }
94
+ return lines.join("\n");
95
+ }
96
+ function printDetections(rows) {
97
+ if (rows.length === 0) {
98
+ console.log(chalk.yellow("No detections yet."));
99
+ return;
100
+ }
101
+ const table = new Table({
102
+ head: [chalk.cyan("Time"), chalk.cyan("Track"), chalk.cyan("Conf"), chalk.cyan("At")],
103
+ colWidths: [12, 52, 8, 8],
104
+ wordWrap: true,
105
+ });
106
+ for (const row of rows)
107
+ table.push(formatDetection(row));
108
+ console.log(table.toString());
109
+ }
110
+ function printIngests(rows) {
111
+ if (rows.length === 0) {
112
+ console.log(chalk.yellow("No ingests yet — is the listener posting?"));
113
+ return;
114
+ }
115
+ const table = new Table({
116
+ head: [
117
+ chalk.cyan("Received"),
118
+ chalk.cyan("Source"),
119
+ chalk.cyan("Seq"),
120
+ chalk.cyan("Status"),
121
+ chalk.cyan("Dur"),
122
+ chalk.cyan("Error"),
123
+ ],
124
+ colWidths: [12, 20, 7, 12, 7, 34],
125
+ wordWrap: true,
126
+ });
127
+ for (const r of rows) {
128
+ const paint = r.status === "failed"
129
+ ? chalk.red
130
+ : r.status === "processed"
131
+ ? chalk.green
132
+ : chalk.yellow;
133
+ table.push([
134
+ clock(r.received_at),
135
+ r.source_id,
136
+ r.sequence ?? "—",
137
+ paint(r.status),
138
+ r.duration_seconds ? `${r.duration_seconds.toFixed(0)}s` : "—",
139
+ r.error ?? "",
140
+ ]);
141
+ }
142
+ console.log(table.toString());
143
+ }
144
+ export function addVinylCommands(program) {
145
+ const vinyl = program
146
+ .command("vinyl")
147
+ .description("Inspect the automatic vinyl play tracking pipeline");
148
+ vinyl
149
+ .command("status")
150
+ .description("Is the pipeline working? Index, queue, ingests, match rate")
151
+ .option("--minutes <n>", "Window to summarise", intOption, 60)
152
+ .option("--source <id>", "Limit to one listener source")
153
+ .option("--json", "Output as JSON")
154
+ .action(async (opts) => {
155
+ try {
156
+ const stats = await makeClient().getIngestStats({
157
+ minutes: opts.minutes,
158
+ source_id: opts.source,
159
+ });
160
+ if (opts.json)
161
+ printJson(stats);
162
+ else
163
+ console.log(formatStats(stats));
164
+ // A pipeline that cannot match is a failure worth an exit code, so
165
+ // this composes in a health check.
166
+ if (!stats.index.engine_registered || stats.index.empty) {
167
+ process.exitCode = 1;
168
+ }
169
+ }
170
+ catch (err) {
171
+ printError(err instanceof Error ? err.message : String(err));
172
+ process.exit(1);
173
+ }
174
+ });
175
+ vinyl
176
+ .command("detections")
177
+ .description("Recent matcher windows, including the no-match ones")
178
+ .option("--source <id>", "Limit to one listener source")
179
+ .option("--session <id>", "Limit to one listening session")
180
+ .option("--matched", "Only windows that matched something")
181
+ .option("--no-match", "Only windows that matched nothing")
182
+ .option("--limit <n>", "How many", intOption, 30)
183
+ .option("--json", "Output as JSON")
184
+ .action(async (opts) => {
185
+ try {
186
+ // commander turns --no-match into `match: false`.
187
+ const matched = opts.match === false ? false : opts.matched ? true : undefined;
188
+ const result = await makeClient().listDetections({
189
+ source_id: opts.source,
190
+ session_id: opts.session,
191
+ matched,
192
+ limit: opts.limit,
193
+ });
194
+ if (opts.json)
195
+ printJson(result);
196
+ else
197
+ printDetections(result.detections);
198
+ }
199
+ catch (err) {
200
+ printError(err instanceof Error ? err.message : String(err));
201
+ process.exit(1);
202
+ }
203
+ });
204
+ vinyl
205
+ .command("ingests")
206
+ .description("Recent audio chunks and what became of them")
207
+ .option("--source <id>", "Limit to one listener source")
208
+ .option("--status <s>", "received | processing | processed | failed")
209
+ .option("--limit <n>", "How many", intOption, 30)
210
+ .option("--json", "Output as JSON")
211
+ .action(async (opts) => {
212
+ try {
213
+ const result = await makeClient().listIngests({
214
+ source_id: opts.source,
215
+ status: opts.status,
216
+ limit: opts.limit,
217
+ });
218
+ if (opts.json)
219
+ printJson(result);
220
+ else
221
+ printIngests(result.ingests);
222
+ }
223
+ catch (err) {
224
+ printError(err instanceof Error ? err.message : String(err));
225
+ process.exit(1);
226
+ }
227
+ });
228
+ }
229
+ //# sourceMappingURL=vinyl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vinyl.js","sourceRoot":"","sources":["../../src/commands/vinyl.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAMhE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,OAAO,IAAI,eAAe,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,WAAW,EAAE,GAAG,CAAC,YAAY;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,GAAkB;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,CAAC;AAC5C,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,CAAkB;IAChD,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAC9D,OAAO;QACL,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC;QACxB,GAAG,CAAC,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,KAAK,IAAI,GAAG,EAAE;QACxC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5B,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,CAAsB;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CACnD,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAC1E,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,cAAc,SAAS,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;IACxB,KAAK,CAAC,IAAI,CACR,CAAC,KAAK,IAAI;QACR,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,+CAA+C,CAAC;QAC/D,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CACtC,CAAC;IAEF,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,cAAc,OAAO,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;IAEhF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;IACvB,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACjF,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,IAAI,CACR,iBAAiB,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,OAAO,YAAY;YAC1D,GAAG,CAAC,CAAC,QAAQ,cAAc,IAAI,GAAG,CACrC,CACF,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACrC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,MAAM,CACV,uBAAuB,CAAC,CAAC,MAAM,UAAU,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAChE,CACF,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,eAAe,CAAC,IAAuB;IAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrF,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACzB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,YAAY,CAAC,IAAoB;IACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE;YACJ,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;SACpB;QACD,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,KAAK,GACT,CAAC,CAAC,MAAM,KAAK,QAAQ;YACnB,CAAC,CAAC,KAAK,CAAC,GAAG;YACX,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW;gBACxB,CAAC,CAAC,KAAK,CAAC,KAAK;gBACb,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC;YACT,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;YACpB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,QAAQ,IAAI,GAAG;YACjB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YACf,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YAC9D,CAAC,CAAC,KAAK,IAAI,EAAE;SACd,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,oDAAoD,CAAC,CAAC;IAErE,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,eAAe,EAAE,qBAAqB,EAAE,SAAS,EAAE,EAAE,CAAC;SAC7D,MAAM,CAAC,eAAe,EAAE,8BAA8B,CAAC;SACvD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,KAAK,EAAE,IAA0D,EAAE,EAAE;QAC3E,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,UAAU,EAAE,CAAC,cAAc,CAAC;gBAC9C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,IAAI;gBAAE,SAAS,CAAC,KAAK,CAAC,CAAC;;gBAC3B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACrC,mEAAmE;YACnE,mCAAmC;YACnC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,UAAU,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,KAAK;SACF,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,eAAe,EAAE,8BAA8B,CAAC;SACvD,MAAM,CAAC,gBAAgB,EAAE,gCAAgC,CAAC;SAC1D,MAAM,CAAC,WAAW,EAAE,qCAAqC,CAAC;SAC1D,MAAM,CAAC,YAAY,EAAE,mCAAmC,CAAC;SACzD,MAAM,CAAC,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC;SAChD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CACL,KAAK,EAAE,IAON,EAAE,EAAE;QACH,IAAI,CAAC;YACH,kDAAkD;YAClD,MAAM,OAAO,GACX,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACjE,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC,cAAc,CAAC;gBAC/C,SAAS,EAAE,IAAI,CAAC,MAAM;gBACtB,UAAU,EAAE,IAAI,CAAC,OAAO;gBACxB,OAAO;gBACP,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,IAAI;gBAAE,SAAS,CAAC,MAAM,CAAC,CAAC;;gBAC5B,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,UAAU,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;IAEJ,KAAK;SACF,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,MAAM,CAAC,eAAe,EAAE,8BAA8B,CAAC;SACvD,MAAM,CAAC,cAAc,EAAE,4CAA4C,CAAC;SACpE,MAAM,CAAC,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC;SAChD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CACL,KAAK,EAAE,IAAyE,EAAE,EAAE;QAClF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC,WAAW,CAAC;gBAC5C,SAAS,EAAE,IAAI,CAAC,MAAM;gBACtB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,IAAI;gBAAE,SAAS,CAAC,MAAM,CAAC,CAAC;;gBAC5B,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,UAAU,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Parse a numeric option.
3
+ *
4
+ * Commander calls a coercion function as `(value, previous)`, so passing bare
5
+ * `parseInt` alongside a default silently turns that default into the **radix**:
6
+ *
7
+ * .option("--limit <n>", "…", parseInt, 20) // parseInt("15", 20) === 25
8
+ * .option("--minutes <n>", "…", parseInt, 60) // radix out of range -> NaN
9
+ *
10
+ * Neither fails loudly. The first quietly returns the wrong number of results,
11
+ * the second yields NaN and whatever that does downstream — `setTimeout(NaN)`
12
+ * fires immediately, so a poll interval becomes a busy loop.
13
+ *
14
+ * This ignores `previous`, parses base 10, and rejects nonsense outright rather
15
+ * than letting NaN travel.
16
+ */
17
+ export declare function intOption(value: string): number;
18
+ /** `intOption`, refusing anything below `min` (default 0). */
19
+ export declare function boundedIntOption(min?: number): (value: string) => number;
20
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,GAAG,SAAI,WACvB,MAAM,KAAG,MAAM,CAO/B"}
@@ -0,0 +1,35 @@
1
+ import { InvalidArgumentError } from "commander";
2
+ /**
3
+ * Parse a numeric option.
4
+ *
5
+ * Commander calls a coercion function as `(value, previous)`, so passing bare
6
+ * `parseInt` alongside a default silently turns that default into the **radix**:
7
+ *
8
+ * .option("--limit <n>", "…", parseInt, 20) // parseInt("15", 20) === 25
9
+ * .option("--minutes <n>", "…", parseInt, 60) // radix out of range -> NaN
10
+ *
11
+ * Neither fails loudly. The first quietly returns the wrong number of results,
12
+ * the second yields NaN and whatever that does downstream — `setTimeout(NaN)`
13
+ * fires immediately, so a poll interval becomes a busy loop.
14
+ *
15
+ * This ignores `previous`, parses base 10, and rejects nonsense outright rather
16
+ * than letting NaN travel.
17
+ */
18
+ export function intOption(value) {
19
+ const parsed = Number.parseInt(value, 10);
20
+ if (Number.isNaN(parsed)) {
21
+ throw new InvalidArgumentError("expected a number");
22
+ }
23
+ return parsed;
24
+ }
25
+ /** `intOption`, refusing anything below `min` (default 0). */
26
+ export function boundedIntOption(min = 0) {
27
+ return (value) => {
28
+ const parsed = intOption(value);
29
+ if (parsed < min) {
30
+ throw new InvalidArgumentError(`must be ${min} or greater`);
31
+ }
32
+ return parsed;
33
+ };
34
+ }
35
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,GAAG,GAAG,CAAC;IACtC,OAAO,CAAC,KAAa,EAAU,EAAE;QAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,oBAAoB,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groovenet/cli",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "CLI for managing your Groovenet DJ collection",
5
5
  "type": "module",
6
6
  "engines": {
@@ -12,7 +12,10 @@
12
12
  "scripts": {
13
13
  "build": "tsc",
14
14
  "dev": "tsc --watch",
15
- "start": "node build/bin/groovenet.js"
15
+ "start": "node build/bin/groovenet.js",
16
+ "test": "vitest run",
17
+ "test:coverage": "vitest run --coverage --coverage.reporter=lcov",
18
+ "test:watch": "vitest"
16
19
  },
17
20
  "files": [
18
21
  "build/"
@@ -36,13 +39,15 @@
36
39
  "homepage": "https://github.com/Public-Vinyl-Radio/groovenet/tree/main/packages/groovenet-cli#readme",
37
40
  "bugs": "https://github.com/Public-Vinyl-Radio/groovenet/issues",
38
41
  "dependencies": {
39
- "@groovenet/client": "^2.0.0",
42
+ "@groovenet/client": "^2.2.0",
40
43
  "chalk": "^6",
41
44
  "cli-table3": "^0.6",
42
45
  "commander": "^15"
43
46
  },
44
47
  "devDependencies": {
45
48
  "@types/node": "^26.4.1",
46
- "typescript": "^7.0"
49
+ "@vitest/coverage-v8": "^5.0.0",
50
+ "typescript": "^7.0",
51
+ "vitest": "^5.0.0"
47
52
  }
48
53
  }