From 4ad080afb0d48ae5b702ef2af0042ce387268951 Mon Sep 17 00:00:00 2001 From: Recoup Agent Date: Fri, 13 Mar 2026 13:56:19 +0000 Subject: [PATCH] agent: @U0AJM7X8FBR API - slack client we want to expand our current Slack inte --- __tests__/bin.test.ts | 12 ++--- __tests__/client.test.ts | 6 +-- __tests__/commands/artists.test.ts | 10 ++--- __tests__/commands/chats.test.ts | 10 ++--- __tests__/commands/notifications.test.ts | 56 ++++++------------------ __tests__/commands/orgs.test.ts | 10 ++--- __tests__/commands/sandboxes.test.ts | 19 +++----- __tests__/commands/songs.test.ts | 55 +++++++++++++++-------- __tests__/commands/whoami.test.ts | 10 ++--- __tests__/output.test.ts | 8 +--- src/bin.ts | 5 +-- src/client.ts | 20 +++++---- src/commands/artists.ts | 2 +- src/commands/chats.ts | 4 +- src/commands/notifications.ts | 13 ++++-- src/commands/orgs.ts | 2 +- src/commands/sandboxes.ts | 4 +- src/commands/songs.ts | 8 ++-- src/commands/whoami.ts | 2 +- src/config.ts | 10 +++-- src/output.ts | 30 ++++++++----- 21 files changed, 139 insertions(+), 157 deletions(-) diff --git a/__tests__/bin.test.ts b/__tests__/bin.test.ts index aa1c0ea..df9a5b0 100644 --- a/__tests__/bin.test.ts +++ b/__tests__/bin.test.ts @@ -5,15 +5,11 @@ import { execFileSync } from "node:child_process"; describe("CLI version", () => { it("reports the version from package.json", () => { - const pkg = JSON.parse( - readFileSync(join(__dirname, "..", "package.json"), "utf-8"), - ); + const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")); - const output = execFileSync( - "node", - [join(__dirname, "..", "dist", "bin.cjs"), "--version"], - { encoding: "utf-8" }, - ).trim(); + const output = execFileSync("node", [join(__dirname, "..", "dist", "bin.cjs"), "--version"], { + encoding: "utf-8", + }).trim(); expect(output).toBe(pkg.version); }); diff --git a/__tests__/client.test.ts b/__tests__/client.test.ts index 40ff3c0..c8860e0 100644 --- a/__tests__/client.test.ts +++ b/__tests__/client.test.ts @@ -73,8 +73,7 @@ describe("get", () => { it("throws on API error status", async () => { mockFetch.mockResolvedValue({ ok: true, - json: () => - Promise.resolve({ status: "error", error: "Something went wrong" }), + json: () => Promise.resolve({ status: "error", error: "Something went wrong" }), }); await expect(get("/api/test")).rejects.toThrow("Something went wrong"); @@ -105,8 +104,7 @@ describe("post", () => { mockFetch.mockResolvedValue({ ok: false, status: 400, - json: () => - Promise.resolve({ status: "error", message: "Bad request" }), + json: () => Promise.resolve({ status: "error", message: "Bad request" }), }); await expect(post("/api/test", {})).rejects.toThrow("Bad request"); diff --git a/__tests__/commands/artists.test.ts b/__tests__/commands/artists.test.ts index b6de57a..86589f9 100644 --- a/__tests__/commands/artists.test.ts +++ b/__tests__/commands/artists.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { artistsCommand } from "../../src/commands/artists.js"; +import { get } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { artistsCommand } from "../../src/commands/artists.js"; -import { get } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { diff --git a/__tests__/commands/chats.test.ts b/__tests__/commands/chats.test.ts index aa9a5cc..c540257 100644 --- a/__tests__/commands/chats.test.ts +++ b/__tests__/commands/chats.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { chatsCommand } from "../../src/commands/chats.js"; +import { get, post } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { chatsCommand } from "../../src/commands/chats.js"; -import { get, post } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { diff --git a/__tests__/commands/notifications.test.ts b/__tests__/commands/notifications.test.ts index fd577e9..4c4c786 100644 --- a/__tests__/commands/notifications.test.ts +++ b/__tests__/commands/notifications.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { notificationsCommand } from "../../src/commands/notifications.js"; +import { post } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { notificationsCommand } from "../../src/commands/notifications.js"; -import { post } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { @@ -32,10 +30,9 @@ describe("notifications command", () => { id: "email-123", }); - await notificationsCommand.parseAsync( - ["--subject", "Test Subject", "--text", "Hello world"], - { from: "user" }, - ); + await notificationsCommand.parseAsync(["--subject", "Test Subject", "--text", "Hello world"], { + from: "user", + }); expect(post).toHaveBeenCalledWith("/api/notifications", { subject: "Test Subject", @@ -70,16 +67,7 @@ describe("notifications command", () => { }); await notificationsCommand.parseAsync( - [ - "--subject", - "Update", - "--text", - "Hello", - "--cc", - "cc@example.com", - "--room-id", - "room-abc", - ], + ["--subject", "Update", "--text", "Hello", "--cc", "cc@example.com", "--room-id", "room-abc"], { from: "user" }, ); @@ -99,14 +87,7 @@ describe("notifications command", () => { }); await notificationsCommand.parseAsync( - [ - "--subject", - "Update", - "--cc", - "a@example.com", - "--cc", - "b@example.com", - ], + ["--subject", "Update", "--cc", "a@example.com", "--cc", "b@example.com"], { from: "user" }, ); @@ -124,14 +105,9 @@ describe("notifications command", () => { }; vi.mocked(post).mockResolvedValue(response); - await notificationsCommand.parseAsync( - ["--subject", "Test", "--json"], - { from: "user" }, - ); + await notificationsCommand.parseAsync(["--subject", "Test", "--json"], { from: "user" }); - expect(logSpy).toHaveBeenCalledWith( - JSON.stringify(response, null, 2), - ); + expect(logSpy).toHaveBeenCalledWith(JSON.stringify(response, null, 2)); }); it("passes account_id when --account flag is provided", async () => { @@ -167,10 +143,7 @@ describe("notifications command", () => { id: "email-no-account", }); - await notificationsCommand.parseAsync( - ["--subject", "Test"], - { from: "user" }, - ); + await notificationsCommand.parseAsync(["--subject", "Test"], { from: "user" }); expect(post).toHaveBeenCalledWith("/api/notifications", { subject: "Test", @@ -180,10 +153,7 @@ describe("notifications command", () => { it("prints error on failure", async () => { vi.mocked(post).mockRejectedValue(new Error("No email address found")); - await notificationsCommand.parseAsync( - ["--subject", "Test"], - { from: "user" }, - ); + await notificationsCommand.parseAsync(["--subject", "Test"], { from: "user" }); expect(errorSpy).toHaveBeenCalledWith("Error: No email address found"); expect(exitSpy).toHaveBeenCalledWith(1); diff --git a/__tests__/commands/orgs.test.ts b/__tests__/commands/orgs.test.ts index 3b10431..8ab4c50 100644 --- a/__tests__/commands/orgs.test.ts +++ b/__tests__/commands/orgs.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { orgsCommand } from "../../src/commands/orgs.js"; +import { get } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { orgsCommand } from "../../src/commands/orgs.js"; -import { get } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { diff --git a/__tests__/commands/sandboxes.test.ts b/__tests__/commands/sandboxes.test.ts index 3dcdedf..4da5e8f 100644 --- a/__tests__/commands/sandboxes.test.ts +++ b/__tests__/commands/sandboxes.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { sandboxesCommand } from "../../src/commands/sandboxes.js"; +import { get, post } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { sandboxesCommand } from "../../src/commands/sandboxes.js"; -import { get, post } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { @@ -44,9 +42,7 @@ describe("sandboxes list", () => { }); it("prints JSON with --json flag", async () => { - const sandboxes = [ - { sandboxId: "sb-1", sandboxStatus: "running", createdAt: "2025-01-01" }, - ]; + const sandboxes = [{ sandboxId: "sb-1", sandboxStatus: "running", createdAt: "2025-01-01" }]; vi.mocked(get).mockResolvedValue({ status: "success", sandboxes }); await sandboxesCommand.parseAsync(["list", "--json"], { from: "user" }); @@ -74,10 +70,7 @@ describe("sandboxes create", () => { sandboxes: [{ sandboxId: "sb-new" }], }); - await sandboxesCommand.parseAsync( - ["create", "--command", "echo hello"], - { from: "user" }, - ); + await sandboxesCommand.parseAsync(["create", "--command", "echo hello"], { from: "user" }); expect(post).toHaveBeenCalledWith("/api/sandboxes", { command: "echo hello", diff --git a/__tests__/commands/songs.test.ts b/__tests__/commands/songs.test.ts index c8cfa3f..3125974 100644 --- a/__tests__/commands/songs.test.ts +++ b/__tests__/commands/songs.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { songsCommand } from "../../src/commands/songs.js"; +import { get, post } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { songsCommand } from "../../src/commands/songs.js"; -import { get, post } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { @@ -47,7 +45,10 @@ describe("songs analyze", () => { elapsed_seconds: 8.0, }); - await songsCommand.parseAsync(["analyze", "--preset", "catalog_metadata", "--audio", "https://example.com/song.mp3"], { from: "user" }); + await songsCommand.parseAsync( + ["analyze", "--preset", "catalog_metadata", "--audio", "https://example.com/song.mp3"], + { from: "user" }, + ); expect(post).toHaveBeenCalledWith("/api/songs/analyze", { preset: "catalog_metadata", @@ -62,7 +63,9 @@ describe("songs analyze", () => { elapsed_seconds: 2.5, }); - await songsCommand.parseAsync(["analyze", "--prompt", "Describe this track."], { from: "user" }); + await songsCommand.parseAsync(["analyze", "--prompt", "Describe this track."], { + from: "user", + }); expect(logSpy).toHaveBeenCalledWith("This is a jazz piece in Bb major."); }); @@ -74,11 +77,12 @@ describe("songs analyze", () => { elapsed_seconds: 10.0, }); - await songsCommand.parseAsync(["analyze", "--preset", "catalog_metadata", "--audio", "https://example.com/song.mp3"], { from: "user" }); - - expect(logSpy).toHaveBeenCalledWith( - JSON.stringify({ genre: "pop", tempo_bpm: 96 }, null, 2), + await songsCommand.parseAsync( + ["analyze", "--preset", "catalog_metadata", "--audio", "https://example.com/song.mp3"], + { from: "user" }, ); + + expect(logSpy).toHaveBeenCalledWith(JSON.stringify({ genre: "pop", tempo_bpm: 96 }, null, 2)); }); it("prints full JSON with --json flag", async () => { @@ -89,7 +93,9 @@ describe("songs analyze", () => { }; vi.mocked(post).mockResolvedValue(data); - await songsCommand.parseAsync(["analyze", "--prompt", "Describe this.", "--json"], { from: "user" }); + await songsCommand.parseAsync(["analyze", "--prompt", "Describe this.", "--json"], { + from: "user", + }); expect(logSpy).toHaveBeenCalledWith(JSON.stringify(data, null, 2)); }); @@ -101,7 +107,10 @@ describe("songs analyze", () => { elapsed_seconds: 10.0, }); - await songsCommand.parseAsync(["analyze", "--prompt", "Describe this.", "--audio", "https://example.com/song.mp3"], { from: "user" }); + await songsCommand.parseAsync( + ["analyze", "--prompt", "Describe this.", "--audio", "https://example.com/song.mp3"], + { from: "user" }, + ); expect(post).toHaveBeenCalledWith("/api/songs/analyze", { prompt: "Describe this.", @@ -131,8 +140,18 @@ describe("songs presets", () => { vi.mocked(get).mockResolvedValue({ status: "success", presets: [ - { name: "catalog_metadata", description: "Catalog enrichment", requiresAudio: true, responseFormat: "json" }, - { name: "mood_tags", description: "Mood tags", requiresAudio: true, responseFormat: "json" }, + { + name: "catalog_metadata", + description: "Catalog enrichment", + requiresAudio: true, + responseFormat: "json", + }, + { + name: "mood_tags", + description: "Mood tags", + requiresAudio: true, + responseFormat: "json", + }, ], }); @@ -143,9 +162,7 @@ describe("songs presets", () => { }); it("prints JSON with --json flag", async () => { - const presets = [ - { name: "catalog_metadata", description: "Catalog enrichment" }, - ]; + const presets = [{ name: "catalog_metadata", description: "Catalog enrichment" }]; vi.mocked(get).mockResolvedValue({ status: "success", presets }); await songsCommand.parseAsync(["presets", "--json"], { from: "user" }); diff --git a/__tests__/commands/whoami.test.ts b/__tests__/commands/whoami.test.ts index ae3d2dd..1c5a770 100644 --- a/__tests__/commands/whoami.test.ts +++ b/__tests__/commands/whoami.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { whoamiCommand } from "../../src/commands/whoami.js"; +import { get } from "../../src/client.js"; + vi.mock("../../src/client.js", () => ({ get: vi.fn(), post: vi.fn(), })); -import { whoamiCommand } from "../../src/commands/whoami.js"; -import { get } from "../../src/client.js"; - let logSpy: ReturnType; let errorSpy: ReturnType; let exitSpy: ReturnType; @@ -15,9 +15,7 @@ let exitSpy: ReturnType; beforeEach(() => { logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); }); afterEach(() => { diff --git a/__tests__/output.test.ts b/__tests__/output.test.ts index 5311739..ef7c56d 100644 --- a/__tests__/output.test.ts +++ b/__tests__/output.test.ts @@ -16,9 +16,7 @@ afterEach(() => { describe("printJson", () => { it("prints formatted JSON", () => { printJson({ foo: "bar", count: 42 }); - expect(logSpy).toHaveBeenCalledWith( - JSON.stringify({ foo: "bar", count: 42 }, null, 2), - ); + expect(logSpy).toHaveBeenCalledWith(JSON.stringify({ foo: "bar", count: 42 }, null, 2)); }); }); @@ -62,9 +60,7 @@ describe("printTable", () => { describe("printError", () => { it("prints error to stderr and exits", () => { - const exitSpy = vi - .spyOn(process, "exit") - .mockImplementation(() => undefined as never); + const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never); printError("something failed"); diff --git a/src/bin.ts b/src/bin.ts index f687860..58f33ec 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -14,10 +14,7 @@ const { version } = JSON.parse(readFileSync(pkgPath, "utf-8")); const program = new Command(); -program - .name("recoup") - .description("Recoup platform CLI") - .version(version); +program.name("recoup").description("Recoup platform CLI").version(version); program.addCommand(whoamiCommand); program.addCommand(artistsCommand); diff --git a/src/client.ts b/src/client.ts index d2d326a..beeda5b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -7,10 +7,12 @@ export interface ApiResponse { [key: string]: unknown; } -export async function get( - path: string, - params?: Record, -): Promise { +/** + * + * @param path + * @param params + */ +export async function get(path: string, params?: Record): Promise { const baseUrl = getBaseUrl(); const url = new URL(path, baseUrl); if (params) { @@ -38,10 +40,12 @@ export async function get( return data; } -export async function post( - path: string, - body: Record, -): Promise { +/** + * + * @param path + * @param body + */ +export async function post(path: string, body: Record): Promise { const baseUrl = getBaseUrl(); const url = new URL(path, baseUrl); diff --git a/src/commands/artists.ts b/src/commands/artists.ts index 123d834..518e344 100644 --- a/src/commands/artists.ts +++ b/src/commands/artists.ts @@ -7,7 +7,7 @@ const listCommand = new Command("list") .option("--json", "Output as JSON") .option("--org ", "Filter by organization ID") .option("--account ", "Filter by account ID") - .action(async (opts) => { + .action(async opts => { try { const params: Record = {}; if (opts.org) params.org_id = opts.org; diff --git a/src/commands/chats.ts b/src/commands/chats.ts index 65761b1..390369d 100644 --- a/src/commands/chats.ts +++ b/src/commands/chats.ts @@ -5,7 +5,7 @@ import { printJson, printTable, printError } from "../output.js"; const listCommand = new Command("list") .description("List chats for the current account") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const data = await get("/api/chats"); const chats = (data.chats as Record[]) || []; @@ -29,7 +29,7 @@ const createCommand = new Command("create") .option("--name ", "Chat topic") .option("--artist ", "Artist ID") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const body: Record = {}; if (opts.name) body.topic = opts.name; diff --git a/src/commands/notifications.ts b/src/commands/notifications.ts index 5e33011..474c52b 100644 --- a/src/commands/notifications.ts +++ b/src/commands/notifications.ts @@ -3,15 +3,22 @@ import { post } from "../client.js"; import { printJson, printError } from "../output.js"; export const notificationsCommand = new Command("notifications") - .description("Send an email to the account owner. The recipient is automatically resolved from your API key — no --to flag needed. Only --subject is required.") + .description( + "Send an email to the account owner. The recipient is automatically resolved from your API key — no --to flag needed. Only --subject is required.", + ) .requiredOption("--subject ", "Email subject line") .option("--text ", "Plain text or Markdown body") .option("--html ", "Raw HTML body (takes precedence over --text)") - .option("--cc ", "CC recipient (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[]) + .option( + "--cc ", + "CC recipient (repeatable)", + (val: string, prev: string[]) => prev.concat(val), + [] as string[], + ) .option("--room-id ", "Room ID for chat link in footer") .option("--account ", "Send to a specific account (org keys only)") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const body: Record = { subject: opts.subject, diff --git a/src/commands/orgs.ts b/src/commands/orgs.ts index 92443d9..c1afd5c 100644 --- a/src/commands/orgs.ts +++ b/src/commands/orgs.ts @@ -6,7 +6,7 @@ const listCommand = new Command("list") .description("List organizations for the current account") .option("--json", "Output as JSON") .option("--account ", "Filter by account ID") - .action(async (opts) => { + .action(async opts => { try { const params: Record = {}; if (opts.account) params.account_id = opts.account; diff --git a/src/commands/sandboxes.ts b/src/commands/sandboxes.ts index 3a0f17f..09dfa87 100644 --- a/src/commands/sandboxes.ts +++ b/src/commands/sandboxes.ts @@ -5,7 +5,7 @@ import { printJson, printTable, printError } from "../output.js"; const listCommand = new Command("list") .description("List sandboxes for the current account") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const data = await get("/api/sandboxes"); const sandboxes = (data.sandboxes as Record[]) || []; @@ -28,7 +28,7 @@ const createCommand = new Command("create") .description("Create a new sandbox") .option("--command ", "Command to run in sandbox") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const body: Record = {}; if (opts.command) body.command = opts.command; diff --git a/src/commands/songs.ts b/src/commands/songs.ts index 6f48f5d..d8f9bf5 100644 --- a/src/commands/songs.ts +++ b/src/commands/songs.ts @@ -9,10 +9,12 @@ const analyzeCommand = new Command("analyze") .option("--audio ", "Public URL to an audio file (MP3, WAV, FLAC)") .option("--max-tokens ", "Max tokens to generate (default 512)", parseInt) .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { if (!opts.prompt && !opts.preset) { - console.error("Error: Provide --prompt or use --preset . Run 'recoup songs presets' to see available presets."); + console.error( + "Error: Provide --prompt or use --preset . Run 'recoup songs presets' to see available presets.", + ); process.exit(1); } @@ -57,7 +59,7 @@ const analyzeCommand = new Command("analyze") const presetsCommand = new Command("presets") .description("List available analysis presets") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const data = await get("/api/songs/analyze/presets"); const presets = (data.presets as Record[]) || []; diff --git a/src/commands/whoami.ts b/src/commands/whoami.ts index 10f15be..e3ffa60 100644 --- a/src/commands/whoami.ts +++ b/src/commands/whoami.ts @@ -5,7 +5,7 @@ import { printJson, printError } from "../output.js"; export const whoamiCommand = new Command("whoami") .description("Show the current authenticated account") .option("--json", "Output as JSON") - .action(async (opts) => { + .action(async opts => { try { const data = await get("/api/accounts/id"); if (opts.json) { diff --git a/src/config.ts b/src/config.ts index b7381d2..f4271e1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,6 @@ +/** + * + */ export function getApiKey(): string { const key = process.env.RECOUP_API_KEY; if (!key) { @@ -10,8 +13,9 @@ export function getApiKey(): string { return key; } +/** + * + */ export function getBaseUrl(): string { - return ( - process.env.RECOUP_API_URL || "https://recoup-api.vercel.app" - ); + return process.env.RECOUP_API_URL || "https://recoup-api.vercel.app"; } diff --git a/src/output.ts b/src/output.ts index ce424b7..0073378 100644 --- a/src/output.ts +++ b/src/output.ts @@ -1,7 +1,16 @@ +/** + * + * @param data + */ export function printJson(data: unknown): void { console.log(JSON.stringify(data, null, 2)); } +/** + * + * @param rows + * @param columns + */ export function printTable( rows: Record[], columns: { key: string; label: string }[], @@ -11,29 +20,26 @@ export function printTable( return; } - const widths = columns.map((col) => - Math.max( - col.label.length, - ...rows.map((row) => String(row[col.key] ?? "").length), - ), + const widths = columns.map(col => + Math.max(col.label.length, ...rows.map(row => String(row[col.key] ?? "").length)), ); - const header = columns - .map((col, i) => col.label.padEnd(widths[i])) - .join(" "); - const separator = widths.map((w) => "-".repeat(w)).join(" "); + const header = columns.map((col, i) => col.label.padEnd(widths[i])).join(" "); + const separator = widths.map(w => "-".repeat(w)).join(" "); console.log(header); console.log(separator); for (const row of rows) { - const line = columns - .map((col, i) => String(row[col.key] ?? "").padEnd(widths[i])) - .join(" "); + const line = columns.map((col, i) => String(row[col.key] ?? "").padEnd(widths[i])).join(" "); console.log(line); } } +/** + * + * @param message + */ export function printError(message: string): void { console.error(`Error: ${message}`); process.exit(1);