From 3d7ce43e1fd2b17325e2c5fb53a71f0fabd38599 Mon Sep 17 00:00:00 2001 From: CTO Agent Date: Tue, 7 Apr 2026 13:46:26 +0000 Subject: [PATCH 1/6] feat: add artist-release-editorial content template Register the new artist-release-editorial template for editorial-style release promos featuring artist press photos, playlist covers, and DSP branding. Co-Authored-By: Paperclip --- lib/content/__tests__/contentTemplates.test.ts | 15 +++++++++++++++ lib/content/contentTemplates.ts | 9 +++++++++ 2 files changed, 24 insertions(+) create mode 100644 lib/content/__tests__/contentTemplates.test.ts diff --git a/lib/content/__tests__/contentTemplates.test.ts b/lib/content/__tests__/contentTemplates.test.ts new file mode 100644 index 00000000..1b1dc2de --- /dev/null +++ b/lib/content/__tests__/contentTemplates.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from "vitest"; +import { CONTENT_TEMPLATES, isSupportedContentTemplate } from "@/lib/content/contentTemplates"; + +describe("contentTemplates", () => { + it("includes artist-release-editorial template", () => { + const template = CONTENT_TEMPLATES.find(t => t.name === "artist-release-editorial"); + expect(template).toBeDefined(); + expect(template!.description).toBeTruthy(); + expect(template!.defaultLipsync).toBe(false); + }); + + it("validates artist-release-editorial as supported", () => { + expect(isSupportedContentTemplate("artist-release-editorial")).toBe(true); + }); +}); diff --git a/lib/content/contentTemplates.ts b/lib/content/contentTemplates.ts index 179c7453..97997ea3 100644 --- a/lib/content/contentTemplates.ts +++ b/lib/content/contentTemplates.ts @@ -25,11 +25,20 @@ export const CONTENT_TEMPLATES: ContentTemplate[] = [ description: "Album art on vinyl in a NYC record store", defaultLipsync: false, }, + { + name: "artist-release-editorial", + description: "Editorial promo featuring artist press photo, playlist covers, and DSP branding", + defaultLipsync: false, + }, ]; /** Derived from the first entry in CONTENT_TEMPLATES to avoid string duplication. */ export const DEFAULT_CONTENT_TEMPLATE = CONTENT_TEMPLATES[0].name; +/** + * + * @param template + */ export function isSupportedContentTemplate(template: string): boolean { return CONTENT_TEMPLATES.some(item => item.name === template); } From 4b2e488b82ad6a369eb7d3d616041cc673e9ca77 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Wed, 8 Apr 2026 08:34:05 -0500 Subject: [PATCH 2/6] fix: extract all image attachments from Slack messages extractMessageAttachments now returns imageUrls (string[]) instead of imageUrl (string | null), collecting all image attachments rather than only the first. registerOnNewMention passes the full array to the content pipeline so multiple playlist covers / logos are forwarded. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../extractMessageAttachments.test.ts | 52 +++++++++++++++---- .../__tests__/registerOnNewMention.test.ts | 51 ++++++++++++++++-- .../content/extractMessageAttachments.ts | 11 ++-- .../content/handlers/registerOnNewMention.ts | 8 +-- 4 files changed, 98 insertions(+), 24 deletions(-) diff --git a/lib/agents/content/__tests__/extractMessageAttachments.test.ts b/lib/agents/content/__tests__/extractMessageAttachments.test.ts index 3db6fc38..61f4ba89 100644 --- a/lib/agents/content/__tests__/extractMessageAttachments.test.ts +++ b/lib/agents/content/__tests__/extractMessageAttachments.test.ts @@ -12,16 +12,16 @@ describe("extractMessageAttachments", () => { vi.clearAllMocks(); }); - it("returns null values when message has no attachments", async () => { + it("returns null/empty values when message has no attachments", async () => { const message = { text: "hello", attachments: [] }; const result = await extractMessageAttachments(message as never); - expect(result).toEqual({ songUrl: null, imageUrl: null }); + expect(result).toEqual({ songUrl: null, imageUrls: [] }); }); - it("returns null values when attachments is undefined", async () => { + it("returns null/empty values when attachments is undefined", async () => { const message = { text: "hello" }; const result = await extractMessageAttachments(message as never); - expect(result).toEqual({ songUrl: null, imageUrl: null }); + expect(result).toEqual({ songUrl: null, imageUrls: [] }); }); it("uploads audio with correct contentType", async () => { @@ -48,7 +48,7 @@ describe("extractMessageAttachments", () => { contentType: "audio/mpeg", }); expect(result.songUrl).toBe("https://blob.vercel-storage.com/content-attachments/my-song.mp3"); - expect(result.imageUrl).toBeNull(); + expect(result.imageUrls).toEqual([]); }); it("extracts and uploads an image attachment", async () => { @@ -69,7 +69,7 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); - expect(result.imageUrl).toBe("https://blob.vercel-storage.com/content-attachments/face.png"); + expect(result.imageUrls).toContain("https://blob.vercel-storage.com/content-attachments/face.png"); expect(result.songUrl).toBeNull(); }); @@ -101,7 +101,39 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); expect(result.songUrl).toBe("https://blob.vercel-storage.com/song.mp3"); - expect(result.imageUrl).toBe("https://blob.vercel-storage.com/photo.jpg"); + expect(result.imageUrls).toContain("https://blob.vercel-storage.com/photo.jpg"); + }); + + it("extracts all image attachments when multiple images are attached", async () => { + const img1 = Buffer.from("img1"); + const img2 = Buffer.from("img2"); + const img3 = Buffer.from("img3"); + const message = { + text: "hello", + attachments: [ + { type: "image", name: "face.png", fetchData: vi.fn().mockResolvedValue(img1) }, + { type: "image", name: "cover1.png", fetchData: vi.fn().mockResolvedValue(img2) }, + { type: "image", name: "cover2.png", fetchData: vi.fn().mockResolvedValue(img3) }, + ], + }; + vi.mocked(put).mockResolvedValueOnce({ + url: "https://blob.vercel-storage.com/face.png", + } as never); + vi.mocked(put).mockResolvedValueOnce({ + url: "https://blob.vercel-storage.com/cover1.png", + } as never); + vi.mocked(put).mockResolvedValueOnce({ + url: "https://blob.vercel-storage.com/cover2.png", + } as never); + + const result = await extractMessageAttachments(message as never); + + expect(result.imageUrls).toHaveLength(3); + expect(result.imageUrls).toEqual([ + "https://blob.vercel-storage.com/face.png", + "https://blob.vercel-storage.com/cover1.png", + "https://blob.vercel-storage.com/cover2.png", + ]); }); it("uses attachment data buffer if fetchData is not available", async () => { @@ -168,7 +200,7 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); - expect(result.imageUrl).toBe("https://blob.vercel-storage.com/photo.jpg"); + expect(result.imageUrls).toContain("https://blob.vercel-storage.com/photo.jpg"); }); it("detects audio from file type with audio mimeType (Slack uploads)", async () => { @@ -205,7 +237,7 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); expect(put).not.toHaveBeenCalled(); - expect(result).toEqual({ songUrl: null, imageUrl: null }); + expect(result).toEqual({ songUrl: null, imageUrls: [] }); }); it("returns null when attachment has no data and no fetchData", async () => { @@ -252,7 +284,7 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); expect(result.songUrl).toBeNull(); - expect(result.imageUrl).toBe("https://blob.vercel-storage.com/photo.jpg"); + expect(result.imageUrls).toEqual(["https://blob.vercel-storage.com/photo.jpg"]); }); it("falls back to generic name when attachment name is missing", async () => { diff --git a/lib/agents/content/__tests__/registerOnNewMention.test.ts b/lib/agents/content/__tests__/registerOnNewMention.test.ts index aedd578d..ec67085e 100644 --- a/lib/agents/content/__tests__/registerOnNewMention.test.ts +++ b/lib/agents/content/__tests__/registerOnNewMention.test.ts @@ -83,7 +83,7 @@ describe("registerOnNewMention", () => { vi.clearAllMocks(); vi.mocked(extractMessageAttachments).mockResolvedValue({ songUrl: null, - imageUrl: null, + imageUrls: [], }); }); @@ -299,7 +299,7 @@ describe("registerOnNewMention", () => { } as never); vi.mocked(extractMessageAttachments).mockResolvedValue({ songUrl: "https://blob.vercel-storage.com/song.mp3", - imageUrl: null, + imageUrls: [], }); vi.mocked(triggerCreateContent).mockResolvedValue({ id: "run-1" }); vi.mocked(triggerPollContentRun).mockResolvedValue(undefined as never); @@ -329,7 +329,7 @@ describe("registerOnNewMention", () => { } as never); vi.mocked(extractMessageAttachments).mockResolvedValue({ songUrl: null, - imageUrl: "https://blob.vercel-storage.com/face.png", + imageUrls: ["https://blob.vercel-storage.com/face.png"], }); vi.mocked(triggerCreateContent).mockResolvedValue({ id: "run-1" }); vi.mocked(triggerPollContentRun).mockResolvedValue(undefined as never); @@ -345,6 +345,47 @@ describe("registerOnNewMention", () => { ); }); + it("passes all image URLs when multiple images are attached", async () => { + const bot = createMockBot(); + registerOnNewMention(bot as never); + + vi.mocked(parseContentPrompt).mockResolvedValue({ + lipsync: false, + batch: 1, + captionLength: "short", + upscale: false, + template: "artist-release-editorial", + }); + vi.mocked(resolveArtistSlug).mockResolvedValue("test-artist"); + vi.mocked(getArtistContentReadiness).mockResolvedValue({ + githubRepo: "https://github.com/test/repo", + } as never); + vi.mocked(extractMessageAttachments).mockResolvedValue({ + songUrl: null, + imageUrls: [ + "https://blob.vercel-storage.com/face.png", + "https://blob.vercel-storage.com/cover1.png", + "https://blob.vercel-storage.com/cover2.png", + ], + }); + vi.mocked(triggerCreateContent).mockResolvedValue({ id: "run-1" }); + vi.mocked(triggerPollContentRun).mockResolvedValue(undefined as never); + + const thread = createMockThread(); + const message = createMockMessage("make an editorial video"); + await bot.getHandler()!(thread, message); + + expect(triggerCreateContent).toHaveBeenCalledWith( + expect.objectContaining({ + images: [ + "https://blob.vercel-storage.com/face.png", + "https://blob.vercel-storage.com/cover1.png", + "https://blob.vercel-storage.com/cover2.png", + ], + }), + ); + }); + it("omits images from payload when no media is attached", async () => { const bot = createMockBot(); registerOnNewMention(bot as never); @@ -388,7 +429,7 @@ describe("registerOnNewMention", () => { } as never); vi.mocked(extractMessageAttachments).mockResolvedValue({ songUrl: "https://blob.vercel-storage.com/song.mp3", - imageUrl: "https://blob.vercel-storage.com/face.png", + imageUrls: ["https://blob.vercel-storage.com/face.png"], }); vi.mocked(triggerCreateContent).mockResolvedValue({ id: "run-1" }); vi.mocked(triggerPollContentRun).mockResolvedValue(undefined as never); @@ -399,7 +440,7 @@ describe("registerOnNewMention", () => { const ackMessage = thread.post.mock.calls[0][0] as string; expect(ackMessage).toContain("Audio: attached file"); - expect(ackMessage).toContain("Image: attached file"); + expect(ackMessage).toContain("Images: 1 attached"); }); it("includes song names in acknowledgment message", async () => { diff --git a/lib/agents/content/extractMessageAttachments.ts b/lib/agents/content/extractMessageAttachments.ts index de40806f..7aceede9 100644 --- a/lib/agents/content/extractMessageAttachments.ts +++ b/lib/agents/content/extractMessageAttachments.ts @@ -15,7 +15,7 @@ interface MessageWithAttachments { export interface ExtractedAttachments { songUrl: string | null; - imageUrl: string | null; + imageUrls: string[]; } /** @@ -29,7 +29,7 @@ export async function extractMessageAttachments( ): Promise { const result: ExtractedAttachments = { songUrl: null, - imageUrl: null, + imageUrls: [], }; const attachments = message.attachments; @@ -41,7 +41,7 @@ export async function extractMessageAttachments( const isImage = (a: Attachment) => a.type === "image" || a.mimeType?.startsWith("image/"); const audioAttachment = attachments.find(isAudio); - const imageAttachment = attachments.find(isImage); + const imageAttachments = attachments.filter(isImage); if (audioAttachment) { try { @@ -51,9 +51,10 @@ export async function extractMessageAttachments( } } - if (imageAttachment) { + for (const imageAttachment of imageAttachments) { try { - result.imageUrl = await resolveAttachmentUrl(imageAttachment, "image"); + const url = await resolveAttachmentUrl(imageAttachment, "image"); + if (url) result.imageUrls.push(url); } catch (error) { console.error("[content-agent] Failed to resolve image attachment:", error); } diff --git a/lib/agents/content/handlers/registerOnNewMention.ts b/lib/agents/content/handlers/registerOnNewMention.ts index 09236116..0ea11d71 100644 --- a/lib/agents/content/handlers/registerOnNewMention.ts +++ b/lib/agents/content/handlers/registerOnNewMention.ts @@ -27,7 +27,7 @@ export function registerOnNewMention(bot: ContentAgentBot) { ); // Extract audio/image attachments from the Slack message - const { songUrl, imageUrl } = await extractMessageAttachments(message); + const { songUrl, imageUrls } = await extractMessageAttachments(message); // Resolve artist slug const artistSlug = await resolveArtistSlug(artistAccountId); @@ -72,8 +72,8 @@ export function registerOnNewMention(bot: ContentAgentBot) { if (songUrl) { details.push("- Audio: attached file"); } - if (imageUrl) { - details.push("- Image: attached file (face guide)"); + if (imageUrls.length > 0) { + details.push(`- Images: ${imageUrls.length} attached`); } await thread.post( `Generating content...\n${details.join("\n")}\n\nI'll reply here when ready (~5-10 min).`, @@ -92,7 +92,7 @@ export function registerOnNewMention(bot: ContentAgentBot) { upscale, githubRepo, ...(allSongs.length > 0 && { songs: allSongs }), - ...(imageUrl && { images: [imageUrl] }), + ...(imageUrls.length > 0 && { images: imageUrls }), }; const results = await Promise.allSettled( From 023643b173ce51d80e1c186f80177cd97f97a713 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Wed, 8 Apr 2026 11:05:23 -0500 Subject: [PATCH 3/6] chore: merge test branch and fix formatting Co-Authored-By: Claude Opus 4.6 (1M context) --- app/api/accounts/[id]/route.ts | 1 + app/api/admins/coding/slack/route.ts | 2 ++ app/api/admins/privy/route.ts | 5 +++++ app/api/chats/[id]/messages/trailing/route.ts | 4 ++++ app/api/songs/analyze/presets/route.ts | 1 + app/api/transcribe/route.ts | 4 ++++ .../__tests__/validateUpdateAccountRequest.test.ts | 4 ++++ lib/accounts/validateUpdateAccountRequest.ts | 2 ++ .../emails/__tests__/validateGetAdminEmailsQuery.test.ts | 4 ++++ lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts | 4 ++++ lib/admins/pr/getPrStatusHandler.ts | 2 ++ lib/admins/privy/countNewAccounts.ts | 3 +++ lib/admins/privy/fetchPrivyLogins.ts | 4 ++++ lib/admins/privy/getCutoffMs.ts | 2 ++ lib/admins/privy/getLatestVerifiedAt.ts | 2 ++ lib/admins/privy/toMs.ts | 2 ++ .../content/__tests__/extractMessageAttachments.test.ts | 4 +++- .../content/__tests__/handleContentAgentCallback.test.ts | 7 +++++++ lib/ai/getModel.ts | 1 + lib/ai/isEmbedModel.ts | 2 ++ lib/artists/__tests__/createArtistPostHandler.test.ts | 5 +++++ lib/artists/__tests__/validateCreateArtistBody.test.ts | 5 +++++ lib/auth/__tests__/validateAuthContext.test.ts | 4 ++++ lib/catalog/formatCatalogSongsAsCSV.ts | 2 ++ lib/catalog/getCatalogDataAsCSV.ts | 2 ++ lib/catalog/getCatalogSongs.ts | 7 +++++++ lib/catalog/getCatalogs.ts | 4 ++++ lib/chat/__tests__/integration/chatEndToEnd.test.ts | 5 +++++ lib/chat/toolChains/getPrepareStepResult.ts | 2 ++ lib/chats/__tests__/createChatHandler.test.ts | 4 ++++ lib/chats/processCompactChatRequest.ts | 3 +++ lib/coding-agent/__tests__/handleGitHubWebhook.test.ts | 6 ++++++ .../__tests__/onMergeTestToMainAction.test.ts | 3 +++ lib/coding-agent/encodeGitHubThreadId.ts | 2 ++ lib/coding-agent/handleMergeSuccess.ts | 2 ++ lib/coding-agent/parseMergeActionId.ts | 2 ++ lib/coding-agent/parseMergeTestToMainActionId.ts | 2 ++ lib/composio/getCallbackUrl.ts | 1 + lib/content/__tests__/validateCreateContentBody.test.ts | 4 ++++ lib/content/getArtistContentReadiness.ts | 5 +++++ lib/content/getArtistFileTree.ts | 3 +++ lib/content/getArtistRootPrefix.ts | 5 +++++ lib/content/getContentValidateHandler.ts | 2 ++ lib/content/isCompletedRun.ts | 4 ++++ lib/content/persistCreateContentRunVideo.ts | 2 ++ lib/content/validateGetContentEstimateQuery.ts | 2 ++ lib/content/validateGetContentValidateQuery.ts | 2 ++ lib/credits/getCreditUsage.ts | 1 + lib/credits/handleChatCredits.ts | 4 ++++ lib/emails/processAndSendEmail.ts | 2 ++ lib/evals/callChatFunctions.ts | 1 + lib/evals/callChatFunctionsWithResult.ts | 2 ++ lib/evals/createToolsCalledScorer.ts | 3 +++ lib/evals/extractTextFromResult.ts | 2 ++ lib/evals/extractTextResultFromSteps.ts | 2 ++ lib/evals/getCatalogSongsCountExpected.ts | 3 +++ lib/evals/getSpotifyFollowersExpected.ts | 4 ++++ lib/evals/scorers/CatalogAvailability.ts | 5 +++++ lib/evals/scorers/QuestionAnswered.ts | 5 +++++ lib/evals/scorers/ToolsCalled.ts | 8 ++++++++ lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts | 3 +++ lib/flamingo/getFlamingoPresetsHandler.ts | 1 + lib/github/__tests__/createOrUpdateFileContent.test.ts | 4 ++-- lib/github/expandSubmoduleEntries.ts | 6 ++++++ lib/github/getRepoGitModules.ts | 3 +++ lib/github/resolveSubmodulePath.ts | 2 ++ lib/mcp/resolveAccountId.ts | 2 ++ lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts | 4 ++++ .../__tests__/createNotificationHandler.test.ts | 4 ++++ .../__tests__/validateCreateNotificationBody.test.ts | 5 +++++ lib/prompts/getSystemPrompt.ts | 1 + lib/slack/getBotChannels.ts | 2 ++ lib/slack/getBotUserId.ts | 2 ++ lib/slack/getSlackUserInfo.ts | 3 +++ lib/spotify/getSpotifyFollowers.ts | 1 + lib/supabase/account_artist_ids/getAccountArtistIds.ts | 4 +++- .../account_workspace_ids/getAccountWorkspaceIds.ts | 2 +- lib/supabase/files/createFileRecord.ts | 2 ++ lib/supabase/song_artists/insertSongArtists.ts | 2 ++ lib/supabase/storage/uploadFileByKey.ts | 6 ++++++ lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts | 6 +++--- lib/tasks/__tests__/getTaskRunHandler.test.ts | 3 +++ lib/tasks/__tests__/validateGetTaskRunQuery.test.ts | 2 ++ lib/tasks/__tests__/validateGetTasksQuery.test.ts | 4 ++++ lib/transcribe/processAudioTranscription.ts | 6 ++++++ lib/transcribe/saveAudioToFiles.ts | 4 ++++ lib/transcribe/saveTranscriptToFiles.ts | 4 ++++ lib/transcribe/types.ts | 2 ++ 88 files changed, 274 insertions(+), 8 deletions(-) diff --git a/app/api/accounts/[id]/route.ts b/app/api/accounts/[id]/route.ts index b272465a..f6d7ace4 100644 --- a/app/api/accounts/[id]/route.ts +++ b/app/api/accounts/[id]/route.ts @@ -25,6 +25,7 @@ export async function OPTIONS() { * - id (required): The unique identifier of the account (UUID) * * @param request - The request object + * @param params.params * @param params - Route params containing the account ID * @returns A NextResponse with account data */ diff --git a/app/api/admins/coding/slack/route.ts b/app/api/admins/coding/slack/route.ts index ea880d30..956d7b4e 100644 --- a/app/api/admins/coding/slack/route.ts +++ b/app/api/admins/coding/slack/route.ts @@ -9,6 +9,8 @@ import { getSlackTagsHandler } from "@/lib/admins/slack/getSlackTagsHandler"; * Pulls directly from the Slack API as the source of truth. * Supports period filtering: all (default), daily, weekly, monthly. * Requires admin authentication. + * + * @param request */ export async function GET(request: NextRequest): Promise { return getSlackTagsHandler(request); diff --git a/app/api/admins/privy/route.ts b/app/api/admins/privy/route.ts index 073bac60..d22ec616 100644 --- a/app/api/admins/privy/route.ts +++ b/app/api/admins/privy/route.ts @@ -8,11 +8,16 @@ import { getPrivyLoginsHandler } from "@/lib/admins/privy/getPrivyLoginsHandler" * Returns Privy login statistics for the requested time period. * Supports daily (last 24h), weekly (last 7 days), and monthly (last 30 days) periods. * Requires admin authentication. + * + * @param request */ export async function GET(request: NextRequest): Promise { return getPrivyLoginsHandler(request); } +/** + * + */ export async function OPTIONS(): Promise { return new NextResponse(null, { status: 204, headers: getCorsHeaders() }); } diff --git a/app/api/chats/[id]/messages/trailing/route.ts b/app/api/chats/[id]/messages/trailing/route.ts index afe9b673..883ba4cc 100644 --- a/app/api/chats/[id]/messages/trailing/route.ts +++ b/app/api/chats/[id]/messages/trailing/route.ts @@ -17,6 +17,10 @@ export async function OPTIONS() { * DELETE /api/chats/[id]/messages/trailing * * Deletes all messages in chat `id` from `from_message_id` onward. + * + * @param request + * @param root0 + * @param root0.params */ export async function DELETE( request: NextRequest, diff --git a/app/api/songs/analyze/presets/route.ts b/app/api/songs/analyze/presets/route.ts index 8baccd38..b809394c 100644 --- a/app/api/songs/analyze/presets/route.ts +++ b/app/api/songs/analyze/presets/route.ts @@ -28,6 +28,7 @@ export async function OPTIONS() { * - status: "success" * - presets: Array of { name, label, description, requiresAudio, responseFormat } * + * @param request * @returns A NextResponse with the list of available presets */ export async function GET(request: NextRequest): Promise { diff --git a/app/api/transcribe/route.ts b/app/api/transcribe/route.ts index 28cf4261..0896806b 100644 --- a/app/api/transcribe/route.ts +++ b/app/api/transcribe/route.ts @@ -2,6 +2,10 @@ import { NextRequest, NextResponse } from "next/server"; import { processAudioTranscription } from "@/lib/transcribe/processAudioTranscription"; import { formatTranscriptionError } from "@/lib/transcribe/types"; +/** + * + * @param req + */ export async function POST(req: NextRequest) { try { const body = await req.json(); diff --git a/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts b/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts index 17f350aa..581723cc 100644 --- a/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts +++ b/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts @@ -16,6 +16,10 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); +/** + * + * @param body + */ function createRequest(body: unknown): NextRequest { return new NextRequest("http://localhost/api/accounts", { method: "PATCH", diff --git a/lib/accounts/validateUpdateAccountRequest.ts b/lib/accounts/validateUpdateAccountRequest.ts index 78e66767..d72667a6 100644 --- a/lib/accounts/validateUpdateAccountRequest.ts +++ b/lib/accounts/validateUpdateAccountRequest.ts @@ -39,6 +39,8 @@ export type ValidatedUpdateAccountRequest = Omit< /** * Validates PATCH /api/accounts including auth, account override access, and body schema. + * + * @param request */ export async function validateUpdateAccountRequest( request: NextRequest, diff --git a/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts b/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts index 90e1a3d0..7531a477 100644 --- a/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts +++ b/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts @@ -12,6 +12,10 @@ vi.mock("@/lib/admins/validateAdminAuth", () => ({ validateAdminAuth: vi.fn(), })); +/** + * + * @param url + */ function createMockRequest(url: string): NextRequest { return { url, diff --git a/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts b/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts index e007e9c8..826b69d6 100644 --- a/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts +++ b/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts @@ -19,6 +19,10 @@ vi.mock("@/lib/github/fetchGithubPrStatus", () => ({ const PR_URL_1 = "https://github.com/recoupable/api/pull/42"; const PR_URL_2 = "https://github.com/recoupable/chat/pull/100"; +/** + * + * @param urls + */ function makeRequest(urls: string[] = [PR_URL_1]) { const params = new URLSearchParams(); urls.forEach(url => params.append("pull_requests", url)); diff --git a/lib/admins/pr/getPrStatusHandler.ts b/lib/admins/pr/getPrStatusHandler.ts index 27081718..73cefa94 100644 --- a/lib/admins/pr/getPrStatusHandler.ts +++ b/lib/admins/pr/getPrStatusHandler.ts @@ -10,6 +10,8 @@ import { fetchGithubPrStatus } from "@/lib/github/fetchGithubPrStatus"; * Uses the GitHub REST API to check each PR's state. * * Requires admin authentication. + * + * @param request */ export async function getPrStatusHandler(request: NextRequest): Promise { try { diff --git a/lib/admins/privy/countNewAccounts.ts b/lib/admins/privy/countNewAccounts.ts index 012ced53..1d34a14a 100644 --- a/lib/admins/privy/countNewAccounts.ts +++ b/lib/admins/privy/countNewAccounts.ts @@ -5,6 +5,9 @@ import { getCutoffMs } from "./getCutoffMs"; /** * Counts how many users in the list were created within the cutoff period. + * + * @param users + * @param period */ export function countNewAccounts(users: User[], period: PrivyLoginsPeriod): number { const cutoffMs = getCutoffMs(period); diff --git a/lib/admins/privy/fetchPrivyLogins.ts b/lib/admins/privy/fetchPrivyLogins.ts index ae4d4dd0..35ac556c 100644 --- a/lib/admins/privy/fetchPrivyLogins.ts +++ b/lib/admins/privy/fetchPrivyLogins.ts @@ -20,6 +20,10 @@ export type FetchPrivyLoginsResult = { totalPrivyUsers: number; }; +/** + * + * @param period + */ export async function fetchPrivyLogins(period: PrivyLoginsPeriod): Promise { const isAll = period === "all"; const cutoffMs = getCutoffMs(period); diff --git a/lib/admins/privy/getCutoffMs.ts b/lib/admins/privy/getCutoffMs.ts index 8b80ec6a..4de0fa32 100644 --- a/lib/admins/privy/getCutoffMs.ts +++ b/lib/admins/privy/getCutoffMs.ts @@ -5,6 +5,8 @@ import { PERIOD_DAYS } from "./periodDays"; * Returns the cutoff timestamp in milliseconds for a given period. * Uses midnight UTC calendar day boundaries to match Privy dashboard behavior. * Returns 0 for "all" (no cutoff). + * + * @param period */ export function getCutoffMs(period: PrivyLoginsPeriod): number { if (period === "all") return 0; diff --git a/lib/admins/privy/getLatestVerifiedAt.ts b/lib/admins/privy/getLatestVerifiedAt.ts index 465ea876..c7f7ba9b 100644 --- a/lib/admins/privy/getLatestVerifiedAt.ts +++ b/lib/admins/privy/getLatestVerifiedAt.ts @@ -4,6 +4,8 @@ import type { User } from "@privy-io/node"; /** * Returns the most recent latest_verified_at (in ms) across all linked_accounts for a Privy user. * Returns null if no linked account has a latest_verified_at. + * + * @param user */ export function getLatestVerifiedAt(user: User): number | null { const linkedAccounts = user.linked_accounts; diff --git a/lib/admins/privy/toMs.ts b/lib/admins/privy/toMs.ts index 472ff9eb..2daad687 100644 --- a/lib/admins/privy/toMs.ts +++ b/lib/admins/privy/toMs.ts @@ -1,6 +1,8 @@ /** * Normalizes a Privy timestamp to milliseconds. * Privy docs say milliseconds but examples show seconds (10 digits). + * + * @param timestamp */ export function toMs(timestamp: number): number { return timestamp > 1e12 ? timestamp : timestamp * 1000; diff --git a/lib/agents/content/__tests__/extractMessageAttachments.test.ts b/lib/agents/content/__tests__/extractMessageAttachments.test.ts index 61f4ba89..4dee2308 100644 --- a/lib/agents/content/__tests__/extractMessageAttachments.test.ts +++ b/lib/agents/content/__tests__/extractMessageAttachments.test.ts @@ -69,7 +69,9 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); - expect(result.imageUrls).toContain("https://blob.vercel-storage.com/content-attachments/face.png"); + expect(result.imageUrls).toContain( + "https://blob.vercel-storage.com/content-attachments/face.png", + ); expect(result.songUrl).toBeNull(); }); diff --git a/lib/agents/content/__tests__/handleContentAgentCallback.test.ts b/lib/agents/content/__tests__/handleContentAgentCallback.test.ts index 36fa4ea1..5edf71a3 100644 --- a/lib/agents/content/__tests__/handleContentAgentCallback.test.ts +++ b/lib/agents/content/__tests__/handleContentAgentCallback.test.ts @@ -84,6 +84,10 @@ describe("handleContentAgentCallback", () => { }); describe("completed callback with videos", () => { + /** + * + * @param body + */ function makeAuthRequest(body: object) { return new Request("http://localhost/api/content-agent/callback", { method: "POST", @@ -92,6 +96,9 @@ describe("handleContentAgentCallback", () => { }); } + /** + * + */ function mockThread() { const thread = { post: vi.fn().mockResolvedValue(undefined), diff --git a/lib/ai/getModel.ts b/lib/ai/getModel.ts index edf4d425..99ca9c2f 100644 --- a/lib/ai/getModel.ts +++ b/lib/ai/getModel.ts @@ -3,6 +3,7 @@ import { GatewayLanguageModelEntry } from "@ai-sdk/gateway"; /** * Returns a specific model by its ID from the list of available models. + * * @param modelId - The ID of the model to find * @returns The matching model or undefined if not found */ diff --git a/lib/ai/isEmbedModel.ts b/lib/ai/isEmbedModel.ts index 7c5fbbfb..4901f1e8 100644 --- a/lib/ai/isEmbedModel.ts +++ b/lib/ai/isEmbedModel.ts @@ -3,6 +3,8 @@ import { GatewayLanguageModelEntry } from "@ai-sdk/gateway"; /** * Determines if a model is an embedding model (not suitable for chat). * Embed models typically have 0 output pricing since they only produce embeddings. + * + * @param m */ export const isEmbedModel = (m: GatewayLanguageModelEntry): boolean => { const pricing = m.pricing; diff --git a/lib/artists/__tests__/createArtistPostHandler.test.ts b/lib/artists/__tests__/createArtistPostHandler.test.ts index e63d244d..dd72b2e1 100644 --- a/lib/artists/__tests__/createArtistPostHandler.test.ts +++ b/lib/artists/__tests__/createArtistPostHandler.test.ts @@ -14,6 +14,11 @@ vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: (...args: unknown[]) => mockValidateAuthContext(...args), })); +/** + * + * @param body + * @param headers + */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json", diff --git a/lib/artists/__tests__/validateCreateArtistBody.test.ts b/lib/artists/__tests__/validateCreateArtistBody.test.ts index 4de5562b..d12fe1ba 100644 --- a/lib/artists/__tests__/validateCreateArtistBody.test.ts +++ b/lib/artists/__tests__/validateCreateArtistBody.test.ts @@ -9,6 +9,11 @@ vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: (...args: unknown[]) => mockValidateAuthContext(...args), })); +/** + * + * @param body + * @param headers + */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json" }; return new NextRequest("http://localhost/api/artists", { diff --git a/lib/auth/__tests__/validateAuthContext.test.ts b/lib/auth/__tests__/validateAuthContext.test.ts index 31dda345..c4769178 100644 --- a/lib/auth/__tests__/validateAuthContext.test.ts +++ b/lib/auth/__tests__/validateAuthContext.test.ts @@ -33,6 +33,10 @@ const mockGetAuthenticatedAccountId = vi.mocked(getAuthenticatedAccountId); const mockValidateOrganizationAccess = vi.mocked(validateOrganizationAccess); const mockCanAccessAccount = vi.mocked(canAccessAccount); +/** + * + * @param headers + */ function createMockRequest(headers: Record = {}): Request { return { headers: { diff --git a/lib/catalog/formatCatalogSongsAsCSV.ts b/lib/catalog/formatCatalogSongsAsCSV.ts index 5115eece..29cc443c 100644 --- a/lib/catalog/formatCatalogSongsAsCSV.ts +++ b/lib/catalog/formatCatalogSongsAsCSV.ts @@ -2,6 +2,8 @@ import { CatalogSong } from "./getCatalogSongs"; /** * Formats catalog songs into the CSV-like format expected by the scorer + * + * @param songs */ export function formatCatalogSongsAsCSV(songs: CatalogSong[]): string { const csvLines = songs.map(song => { diff --git a/lib/catalog/getCatalogDataAsCSV.ts b/lib/catalog/getCatalogDataAsCSV.ts index ea529c37..4a86fc0e 100644 --- a/lib/catalog/getCatalogDataAsCSV.ts +++ b/lib/catalog/getCatalogDataAsCSV.ts @@ -3,6 +3,8 @@ import { formatCatalogSongsAsCSV } from "./formatCatalogSongsAsCSV"; /** * Gets all catalog songs and formats them as CSV for the scorer + * + * @param catalogId */ export async function getCatalogDataAsCSV(catalogId: string): Promise { const allSongs: CatalogSong[] = []; diff --git a/lib/catalog/getCatalogSongs.ts b/lib/catalog/getCatalogSongs.ts index c58c33be..d7b5ca62 100644 --- a/lib/catalog/getCatalogSongs.ts +++ b/lib/catalog/getCatalogSongs.ts @@ -25,6 +25,13 @@ export interface CatalogSongsResponse { error?: string; } +/** + * + * @param catalogId + * @param pageSize + * @param page + * @param artistName + */ export async function getCatalogSongs( catalogId: string, pageSize: number = 100, diff --git a/lib/catalog/getCatalogs.ts b/lib/catalog/getCatalogs.ts index 9533183b..4ac8a842 100644 --- a/lib/catalog/getCatalogs.ts +++ b/lib/catalog/getCatalogs.ts @@ -8,6 +8,10 @@ export interface CatalogsResponse { error?: string; } +/** + * + * @param accountId + */ export async function getCatalogs(accountId: string): Promise { try { const response = await fetch( diff --git a/lib/chat/__tests__/integration/chatEndToEnd.test.ts b/lib/chat/__tests__/integration/chatEndToEnd.test.ts index b54e51f5..f2aaccad 100644 --- a/lib/chat/__tests__/integration/chatEndToEnd.test.ts +++ b/lib/chat/__tests__/integration/chatEndToEnd.test.ts @@ -154,6 +154,11 @@ const mockDeductCredits = vi.mocked(deductCredits); const mockGenerateChatTitle = vi.mocked(generateChatTitle); // Helper to create mock NextRequest +/** + * + * @param body + * @param headers + */ function createMockRequest(body: unknown, headers: Record = {}): Request { return { json: () => Promise.resolve(body), diff --git a/lib/chat/toolChains/getPrepareStepResult.ts b/lib/chat/toolChains/getPrepareStepResult.ts index 02dd8e71..c011c078 100644 --- a/lib/chat/toolChains/getPrepareStepResult.ts +++ b/lib/chat/toolChains/getPrepareStepResult.ts @@ -12,6 +12,8 @@ type PrepareStepOptions = { /** * Returns the next tool to run based on timeline progression through tool chains. * Uses toolCallsContent to track exact execution order and position in sequence. + * + * @param options */ const getPrepareStepResult = (options: PrepareStepOptions): PrepareStepResult | undefined => { const { steps } = options; diff --git a/lib/chats/__tests__/createChatHandler.test.ts b/lib/chats/__tests__/createChatHandler.test.ts index 6d509147..3258d6cf 100644 --- a/lib/chats/__tests__/createChatHandler.test.ts +++ b/lib/chats/__tests__/createChatHandler.test.ts @@ -41,6 +41,10 @@ vi.mock("../generateChatTitle", () => ({ generateChatTitle: vi.fn(), })); +/** + * + * @param headers + */ function createMockRequest( headers: Record = { "x-api-key": "test-api-key" }, ): NextRequest { diff --git a/lib/chats/processCompactChatRequest.ts b/lib/chats/processCompactChatRequest.ts index a1699c93..c98c2e97 100644 --- a/lib/chats/processCompactChatRequest.ts +++ b/lib/chats/processCompactChatRequest.ts @@ -17,6 +17,9 @@ interface ProcessCompactChatRequestParams { * Verifies the chat exists and the user has access before compacting. * * @param params - The parameters for processing the chat compaction. + * @param params.chatId + * @param params.prompt + * @param params.accountId * @returns The result of the compaction attempt. */ export async function processCompactChatRequest({ diff --git a/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts b/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts index 5e059f4e..194a7170 100644 --- a/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts +++ b/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts @@ -45,6 +45,12 @@ const BASE_PAYLOAD = { }, }; +/** + * + * @param body + * @param event + * @param signature + */ function makeRequest(body: unknown, event = "issue_comment", signature = "valid") { return { text: () => Promise.resolve(JSON.stringify(body)), diff --git a/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts b/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts index 8af470e1..f173d6ce 100644 --- a/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts +++ b/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts @@ -12,6 +12,9 @@ beforeEach(() => { process.env.GITHUB_TOKEN = "ghp_test"; }); +/** + * + */ function createMockBot() { return { onAction: vi.fn() } as any; } diff --git a/lib/coding-agent/encodeGitHubThreadId.ts b/lib/coding-agent/encodeGitHubThreadId.ts index 1cfff2fe..f4797e43 100644 --- a/lib/coding-agent/encodeGitHubThreadId.ts +++ b/lib/coding-agent/encodeGitHubThreadId.ts @@ -6,6 +6,8 @@ import type { GitHubThreadId } from "@chat-adapter/github"; * * - PR-level: `github:{owner}/{repo}:{prNumber}` * - Review comment: `github:{owner}/{repo}:{prNumber}:rc:{reviewCommentId}` + * + * @param thread */ export function encodeGitHubThreadId(thread: GitHubThreadId): string { const { owner, repo, prNumber, reviewCommentId } = thread; diff --git a/lib/coding-agent/handleMergeSuccess.ts b/lib/coding-agent/handleMergeSuccess.ts index f026f48d..c241923b 100644 --- a/lib/coding-agent/handleMergeSuccess.ts +++ b/lib/coding-agent/handleMergeSuccess.ts @@ -7,6 +7,8 @@ import type { CodingAgentThreadState } from "./types"; * Handles post-merge cleanup after all PRs merged successfully. * Deletes the shared PR state keys for all repos and persists the latest * snapshot via upsertAccountSnapshot. + * + * @param state */ export async function handleMergeSuccess(state: CodingAgentThreadState): Promise { try { diff --git a/lib/coding-agent/parseMergeActionId.ts b/lib/coding-agent/parseMergeActionId.ts index 5118249e..25fd3eeb 100644 --- a/lib/coding-agent/parseMergeActionId.ts +++ b/lib/coding-agent/parseMergeActionId.ts @@ -1,6 +1,8 @@ /** * Parses a merge action ID like "merge_pr:recoupable/api#42" * into { repo, number } or null if the format doesn't match. + * + * @param actionId */ export function parseMergeActionId(actionId: string) { const match = actionId.match(/^merge_pr:(.+)#(\d+)$/); diff --git a/lib/coding-agent/parseMergeTestToMainActionId.ts b/lib/coding-agent/parseMergeTestToMainActionId.ts index 1228615f..14133eac 100644 --- a/lib/coding-agent/parseMergeTestToMainActionId.ts +++ b/lib/coding-agent/parseMergeTestToMainActionId.ts @@ -1,6 +1,8 @@ /** * Parses a merge_test_to_main action ID like "merge_test_to_main:recoupable/api" * into the repo string, or null if the format doesn't match. + * + * @param actionId */ export function parseMergeTestToMainActionId(actionId: string): string | null { const prefix = "merge_test_to_main:"; diff --git a/lib/composio/getCallbackUrl.ts b/lib/composio/getCallbackUrl.ts index 570c9251..8c83505a 100644 --- a/lib/composio/getCallbackUrl.ts +++ b/lib/composio/getCallbackUrl.ts @@ -19,6 +19,7 @@ interface CallbackOptions { * * @param options.destination - Where to redirect: "chat" or "connectors" * @param options.roomId - For chat destination, the room ID to return to + * @param options * @returns Full callback URL with success indicator */ export function getCallbackUrl(options: CallbackOptions): string { diff --git a/lib/content/__tests__/validateCreateContentBody.test.ts b/lib/content/__tests__/validateCreateContentBody.test.ts index 1a71d5ae..31b1c461 100644 --- a/lib/content/__tests__/validateCreateContentBody.test.ts +++ b/lib/content/__tests__/validateCreateContentBody.test.ts @@ -20,6 +20,10 @@ vi.mock("@/lib/content/resolveArtistSlug", () => ({ resolveArtistSlug: vi.fn().mockResolvedValue("gatsby-grace"), })); +/** + * + * @param body + */ function createRequest(body: unknown): NextRequest { return new NextRequest("http://localhost/api/content/create", { method: "POST", diff --git a/lib/content/getArtistContentReadiness.ts b/lib/content/getArtistContentReadiness.ts index a902ce0f..9238598e 100644 --- a/lib/content/getArtistContentReadiness.ts +++ b/lib/content/getArtistContentReadiness.ts @@ -22,6 +22,11 @@ export interface ArtistContentReadiness { /** * Checks whether an artist has the expected files for content creation. * Searches the main repo and org submodule repos. + * + * @param root0 + * @param root0.accountId + * @param root0.artistAccountId + * @param root0.artistSlug */ export async function getArtistContentReadiness({ accountId, diff --git a/lib/content/getArtistFileTree.ts b/lib/content/getArtistFileTree.ts index 908855a0..b5392b52 100644 --- a/lib/content/getArtistFileTree.ts +++ b/lib/content/getArtistFileTree.ts @@ -4,6 +4,9 @@ import { getOrgRepoUrls } from "@/lib/github/getOrgRepoUrls"; /** * Gets the file tree that contains the artist, checking the main repo * first, then falling back to org submodule repos. + * + * @param githubRepo + * @param artistSlug */ export async function getArtistFileTree( githubRepo: string, diff --git a/lib/content/getArtistRootPrefix.ts b/lib/content/getArtistRootPrefix.ts index 5a777abe..bf81d48a 100644 --- a/lib/content/getArtistRootPrefix.ts +++ b/lib/content/getArtistRootPrefix.ts @@ -1,3 +1,8 @@ +/** + * + * @param paths + * @param artistSlug + */ export function getArtistRootPrefix(paths: string[], artistSlug: string): string { const preferredPrefix = `artists/${artistSlug}/`; if (paths.some(path => path.startsWith(preferredPrefix))) { diff --git a/lib/content/getContentValidateHandler.ts b/lib/content/getContentValidateHandler.ts index e0c758b8..81cd0ce8 100644 --- a/lib/content/getContentValidateHandler.ts +++ b/lib/content/getContentValidateHandler.ts @@ -8,6 +8,8 @@ import { getArtistContentReadiness } from "@/lib/content/getArtistContentReadine * Handler for GET /api/content/validate. * NOTE: Phase 1 returns structural readiness scaffolding. Deep filesystem checks * are performed in the background task before spend-heavy steps. + * + * @param request */ export async function getContentValidateHandler(request: NextRequest): Promise { const validated = await validateGetContentValidateQuery(request); diff --git a/lib/content/isCompletedRun.ts b/lib/content/isCompletedRun.ts index 855ea068..951d20b2 100644 --- a/lib/content/isCompletedRun.ts +++ b/lib/content/isCompletedRun.ts @@ -5,6 +5,10 @@ export type TriggerRunLike = { output?: unknown; }; +/** + * + * @param run + */ export function isCompletedRun(run: TriggerRunLike): boolean { return run.status === "COMPLETED"; } diff --git a/lib/content/persistCreateContentRunVideo.ts b/lib/content/persistCreateContentRunVideo.ts index 25a77eed..69bac792 100644 --- a/lib/content/persistCreateContentRunVideo.ts +++ b/lib/content/persistCreateContentRunVideo.ts @@ -27,6 +27,8 @@ type CreateContentOutput = { * and returns the run with normalized output. * * This keeps Supabase writes in API only. + * + * @param run */ export async function persistCreateContentRunVideo(run: T): Promise { if (run.taskIdentifier !== CREATE_CONTENT_TASK_ID || !isCompletedRun(run)) { diff --git a/lib/content/validateGetContentEstimateQuery.ts b/lib/content/validateGetContentEstimateQuery.ts index 5828e7cc..97af7468 100644 --- a/lib/content/validateGetContentEstimateQuery.ts +++ b/lib/content/validateGetContentEstimateQuery.ts @@ -15,6 +15,8 @@ export type ValidatedGetContentEstimateQuery = z.infer { diff --git a/lib/evals/callChatFunctionsWithResult.ts b/lib/evals/callChatFunctionsWithResult.ts index a792248b..b80fcb58 100644 --- a/lib/evals/callChatFunctionsWithResult.ts +++ b/lib/evals/callChatFunctionsWithResult.ts @@ -8,6 +8,8 @@ import { ChatRequestBody } from "@/lib/chat/validateChatRequest"; * * Note: result.toolCalls only contains calls from the LAST step. When using multi-step * tool chains, we need to collect toolCalls from result.steps to capture all tool usage. + * + * @param input */ export async function callChatFunctionsWithResult(input: string) { const messages: UIMessage[] = [ diff --git a/lib/evals/createToolsCalledScorer.ts b/lib/evals/createToolsCalledScorer.ts index 1d838ee3..8a9ac7e7 100644 --- a/lib/evals/createToolsCalledScorer.ts +++ b/lib/evals/createToolsCalledScorer.ts @@ -3,6 +3,9 @@ import { ToolsCalled } from "./scorers/ToolsCalled"; /** * Creates a scorer that checks if required tools were called. * Handles extracting output text and toolCalls from the task result. + * + * @param requiredTools + * @param penalizedTools */ export const createToolsCalledScorer = (requiredTools: string[], penalizedTools: string[] = []) => { return async (args: { output: unknown; expected?: string; input: string }) => { diff --git a/lib/evals/extractTextFromResult.ts b/lib/evals/extractTextFromResult.ts index fac24cf6..dc67f3ab 100644 --- a/lib/evals/extractTextFromResult.ts +++ b/lib/evals/extractTextFromResult.ts @@ -3,6 +3,8 @@ import { extractTextResultFromSteps } from "./extractTextResultFromSteps"; /** * Extract text from a GenerateTextResult + * + * @param result */ export function extractTextFromResult(result: Awaited>): string { // Handle multi-step responses (when maxSteps > 1) diff --git a/lib/evals/extractTextResultFromSteps.ts b/lib/evals/extractTextResultFromSteps.ts index 44c0ae0d..16881677 100644 --- a/lib/evals/extractTextResultFromSteps.ts +++ b/lib/evals/extractTextResultFromSteps.ts @@ -4,6 +4,8 @@ import type { TextPart } from "ai"; /** * Extract text from multi-step GenerateTextResult * Handles responses where maxSteps > 1 + * + * @param result */ export function extractTextResultFromSteps( result: Awaited>, diff --git a/lib/evals/getCatalogSongsCountExpected.ts b/lib/evals/getCatalogSongsCountExpected.ts index 6f04e59c..d94383ef 100644 --- a/lib/evals/getCatalogSongsCountExpected.ts +++ b/lib/evals/getCatalogSongsCountExpected.ts @@ -2,6 +2,9 @@ import { getCatalogs } from "@/lib/catalog/getCatalogs"; import { getCatalogSongs } from "@/lib/catalog/getCatalogSongs"; import { EVAL_ACCOUNT_ID } from "@/lib/consts"; +/** + * + */ async function getCatalogSongsCountExpected() { try { const catalogsData = await getCatalogs(EVAL_ACCOUNT_ID); diff --git a/lib/evals/getSpotifyFollowersExpected.ts b/lib/evals/getSpotifyFollowersExpected.ts index ef96e248..f5221937 100644 --- a/lib/evals/getSpotifyFollowersExpected.ts +++ b/lib/evals/getSpotifyFollowersExpected.ts @@ -1,5 +1,9 @@ import { getSpotifyFollowers } from "@/lib/spotify/getSpotifyFollowers"; +/** + * + * @param artist + */ async function getSpotifyFollowersExpected(artist: string) { try { const followerCount = await getSpotifyFollowers(artist); diff --git a/lib/evals/scorers/CatalogAvailability.ts b/lib/evals/scorers/CatalogAvailability.ts index f4829ea4..8cf292d9 100644 --- a/lib/evals/scorers/CatalogAvailability.ts +++ b/lib/evals/scorers/CatalogAvailability.ts @@ -5,6 +5,11 @@ import { z } from "zod"; /** * Custom scorer that uses AI to check if recommended songs are actually in the catalog + * + * @param root0 + * @param root0.output + * @param root0.expected + * @param root0.input */ export const CatalogAvailability = async ({ output, diff --git a/lib/evals/scorers/QuestionAnswered.ts b/lib/evals/scorers/QuestionAnswered.ts index abe0222c..a7bafd1d 100644 --- a/lib/evals/scorers/QuestionAnswered.ts +++ b/lib/evals/scorers/QuestionAnswered.ts @@ -5,6 +5,11 @@ import { z } from "zod"; /** * Custom scorer that checks if the AI actually answered the customer's question * with a specific answer, or if it deflected/explained why it couldn't answer + * + * @param root0 + * @param root0.output + * @param root0.expected + * @param root0.input */ export const QuestionAnswered = async ({ output, diff --git a/lib/evals/scorers/ToolsCalled.ts b/lib/evals/scorers/ToolsCalled.ts index 2d901ec3..6a451100 100644 --- a/lib/evals/scorers/ToolsCalled.ts +++ b/lib/evals/scorers/ToolsCalled.ts @@ -1,5 +1,13 @@ /** * Generic scorer that checks if specific tools were called + * + * @param root0 + * @param root0.output + * @param root0.expected + * @param root0.input + * @param root0.toolCalls + * @param root0.requiredTools + * @param root0.penalizedTools */ export const ToolsCalled = async ({ toolCalls, diff --git a/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts b/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts index 19109b2d..1c30d8fc 100644 --- a/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts +++ b/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts @@ -17,6 +17,9 @@ vi.mock("../presets", () => ({ getPresetSummaries: vi.fn(), })); +/** + * + */ function createMockRequest(): NextRequest { return { headers: new Headers({ "x-api-key": "test-key" }), diff --git a/lib/flamingo/getFlamingoPresetsHandler.ts b/lib/flamingo/getFlamingoPresetsHandler.ts index e35b5899..f33d491d 100644 --- a/lib/flamingo/getFlamingoPresetsHandler.ts +++ b/lib/flamingo/getFlamingoPresetsHandler.ts @@ -10,6 +10,7 @@ import { validateAuthContext } from "@/lib/auth/validateAuthContext"; * Returns a list of all available analysis presets. * Requires authentication via x-api-key header or Authorization bearer token. * + * @param request * @returns A NextResponse with the list of available presets. */ export async function getFlamingoPresetsHandler(request: NextRequest): Promise { diff --git a/lib/github/__tests__/createOrUpdateFileContent.test.ts b/lib/github/__tests__/createOrUpdateFileContent.test.ts index 8e2a19a1..f8fee1a1 100644 --- a/lib/github/__tests__/createOrUpdateFileContent.test.ts +++ b/lib/github/__tests__/createOrUpdateFileContent.test.ts @@ -1,12 +1,12 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { createOrUpdateFileContent } from "../createOrUpdateFileContent"; +import { parseGitHubRepoUrl } from "../parseGitHubRepoUrl"; + vi.mock("../parseGitHubRepoUrl", () => ({ parseGitHubRepoUrl: vi.fn(), })); -import { parseGitHubRepoUrl } from "../parseGitHubRepoUrl"; - const mockFetch = vi.fn(); global.fetch = mockFetch; diff --git a/lib/github/expandSubmoduleEntries.ts b/lib/github/expandSubmoduleEntries.ts index 9531bee1..3082c63b 100644 --- a/lib/github/expandSubmoduleEntries.ts +++ b/lib/github/expandSubmoduleEntries.ts @@ -11,9 +11,15 @@ interface SubmoduleRef { * Resolves submodule URLs from .gitmodules, fetches each submodule's tree, * and merges the results into the regular entries with correct path prefixes. * + * @param regularEntries.regularEntries * @param regularEntries - Non-submodule file tree entries * @param submoduleEntries - Submodule references (type "commit" from GitHub Trees API) * @param repo - Repository context for fetching .gitmodules + * @param regularEntries.submoduleEntries + * @param regularEntries.repo + * @param regularEntries.repo.owner + * @param regularEntries.repo.repo + * @param regularEntries.repo.branch * @returns Combined file tree entries with submodules expanded as directories */ export async function expandSubmoduleEntries({ diff --git a/lib/github/getRepoGitModules.ts b/lib/github/getRepoGitModules.ts index caa0304e..8913a6ae 100644 --- a/lib/github/getRepoGitModules.ts +++ b/lib/github/getRepoGitModules.ts @@ -4,9 +4,12 @@ import { parseGitModules, type SubmoduleEntry } from "./parseGitModules"; * Fetches and parses .gitmodules from a GitHub repository. * Uses the GitHub Contents API (works for both public and private repos). * + * @param owner.owner * @param owner - The GitHub repository owner * @param repo - The GitHub repository name * @param branch - The branch to fetch from + * @param owner.repo + * @param owner.branch * @returns Array of submodule entries, or null if .gitmodules doesn't exist or fetch fails */ export async function getRepoGitModules({ diff --git a/lib/github/resolveSubmodulePath.ts b/lib/github/resolveSubmodulePath.ts index 7c3f60ed..029f1b1d 100644 --- a/lib/github/resolveSubmodulePath.ts +++ b/lib/github/resolveSubmodulePath.ts @@ -6,8 +6,10 @@ import { getRepoGitModules } from "./getRepoGitModules"; * If the path falls within a submodule, returns the submodule's repo URL * and the relative path within it. Otherwise returns the original values. * + * @param githubRepo.githubRepo * @param githubRepo - The parent GitHub repository URL * @param path - The file path to resolve + * @param githubRepo.path * @returns The resolved repo URL and path */ export async function resolveSubmodulePath({ diff --git a/lib/mcp/resolveAccountId.ts b/lib/mcp/resolveAccountId.ts index 03d1d0d8..456fe4c6 100644 --- a/lib/mcp/resolveAccountId.ts +++ b/lib/mcp/resolveAccountId.ts @@ -16,6 +16,8 @@ export interface ResolveAccountIdResult { * Validates access when an org API key attempts to use an account_id override. * * @param params - The auth info and optional account_id override. + * @param params.authInfo + * @param params.accountIdOverride * @returns The resolved accountId or an error message. */ export async function resolveAccountId({ diff --git a/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts b/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts index 4942fdfb..d8a64f79 100644 --- a/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts +++ b/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts @@ -15,6 +15,10 @@ const transcribeAudioSchema = z.object({ type TranscribeAudioArgs = z.infer; +/** + * + * @param server + */ export function registerTranscribeAudioTool(server: McpServer): void { server.registerTool( "transcribe_audio", diff --git a/lib/notifications/__tests__/createNotificationHandler.test.ts b/lib/notifications/__tests__/createNotificationHandler.test.ts index ca7fb677..60b6e5ba 100644 --- a/lib/notifications/__tests__/createNotificationHandler.test.ts +++ b/lib/notifications/__tests__/createNotificationHandler.test.ts @@ -26,6 +26,10 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); +/** + * + * @param body + */ function createRequest(body: unknown): NextRequest { return new NextRequest("https://recoup-api.vercel.app/api/notifications", { method: "POST", diff --git a/lib/notifications/__tests__/validateCreateNotificationBody.test.ts b/lib/notifications/__tests__/validateCreateNotificationBody.test.ts index 10390b15..645ccedc 100644 --- a/lib/notifications/__tests__/validateCreateNotificationBody.test.ts +++ b/lib/notifications/__tests__/validateCreateNotificationBody.test.ts @@ -16,6 +16,11 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); +/** + * + * @param body + * @param headers + */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json" }; return new NextRequest("http://localhost/api/notifications", { diff --git a/lib/prompts/getSystemPrompt.ts b/lib/prompts/getSystemPrompt.ts index 54964670..5077609a 100644 --- a/lib/prompts/getSystemPrompt.ts +++ b/lib/prompts/getSystemPrompt.ts @@ -13,6 +13,7 @@ import { AccountWithDetails } from "@/lib/supabase/accounts/getAccountWithDetail * @param params.artistInstruction - The artist instruction * @param params.conversationName - The name of the conversation * @param params.accountWithDetails - The account with details + * @param params.orgId * @returns The system prompt */ export function getSystemPrompt({ diff --git a/lib/slack/getBotChannels.ts b/lib/slack/getBotChannels.ts index 01fb47ff..6c2f905a 100644 --- a/lib/slack/getBotChannels.ts +++ b/lib/slack/getBotChannels.ts @@ -9,6 +9,8 @@ interface ConversationsListResponse { /** * Returns all channels the bot is a member of, paginating through all results. + * + * @param token */ export async function getBotChannels(token: string): Promise> { const channels: Array<{ id: string; name: string }> = []; diff --git a/lib/slack/getBotUserId.ts b/lib/slack/getBotUserId.ts index 1c3e0924..673ec465 100644 --- a/lib/slack/getBotUserId.ts +++ b/lib/slack/getBotUserId.ts @@ -8,6 +8,8 @@ interface AuthTestResponse { /** * Returns the authenticated bot's Slack user ID via auth.test. + * + * @param token */ export async function getBotUserId(token: string): Promise { const authTest = await slackGet("auth.test", token); diff --git a/lib/slack/getSlackUserInfo.ts b/lib/slack/getSlackUserInfo.ts index eb144e45..91873ddf 100644 --- a/lib/slack/getSlackUserInfo.ts +++ b/lib/slack/getSlackUserInfo.ts @@ -16,6 +16,9 @@ interface UsersInfoResponse { /** * Fetches a Slack account's display name and avatar by their Slack ID. + * + * @param token + * @param userId */ export async function getSlackUserInfo( token: string, diff --git a/lib/spotify/getSpotifyFollowers.ts b/lib/spotify/getSpotifyFollowers.ts index 235de41e..acd1c3be 100644 --- a/lib/spotify/getSpotifyFollowers.ts +++ b/lib/spotify/getSpotifyFollowers.ts @@ -37,6 +37,7 @@ interface SpotifySearchResponse { /** * Get Spotify follower count for an artist + * * @param artistName - The name of the artist to search for * @returns Promise - The follower count of the first matching artist */ diff --git a/lib/supabase/account_artist_ids/getAccountArtistIds.ts b/lib/supabase/account_artist_ids/getAccountArtistIds.ts index e4e6b809..42b550d0 100644 --- a/lib/supabase/account_artist_ids/getAccountArtistIds.ts +++ b/lib/supabase/account_artist_ids/getAccountArtistIds.ts @@ -8,7 +8,9 @@ export type AccountArtistRow = ArtistQueryRow & { artist_id: string; pinned: boo * Get all artists for an array of artist IDs or account IDs, with full info. * Returns raw data - formatting should be done by caller. * - * @param params Object with artistIds or accountIds array + * @param params - Object with artistIds or accountIds array + * @param params.artistIds + * @param params.accountIds * @returns Array of raw artist rows from database */ export async function getAccountArtistIds(params: { diff --git a/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts b/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts index ae121fdd..4ca7ad8e 100644 --- a/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts +++ b/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts @@ -10,7 +10,7 @@ export type AccountWorkspaceRow = Omit & { * Get all workspaces for an account, with full info. * Returns raw data - formatting should be done by caller. * - * @param accountId The owner's account ID + * @param accountId - The owner's account ID * @returns Array of raw workspace rows from database */ export async function getAccountWorkspaceIds(accountId: string): Promise { diff --git a/lib/supabase/files/createFileRecord.ts b/lib/supabase/files/createFileRecord.ts index 6f836f3c..3182de11 100644 --- a/lib/supabase/files/createFileRecord.ts +++ b/lib/supabase/files/createFileRecord.ts @@ -25,6 +25,8 @@ export interface CreateFileRecordParams { /** * Create a file record in the database + * + * @param params */ export async function createFileRecord(params: CreateFileRecordParams): Promise { const { diff --git a/lib/supabase/song_artists/insertSongArtists.ts b/lib/supabase/song_artists/insertSongArtists.ts index b81879e3..69878d6d 100644 --- a/lib/supabase/song_artists/insertSongArtists.ts +++ b/lib/supabase/song_artists/insertSongArtists.ts @@ -5,6 +5,8 @@ export type SongArtistInsert = TablesInsert<"song_artists">; /** * Inserts song-artist relationships, skipping duplicates. + * + * @param songArtists */ export async function insertSongArtists(songArtists: SongArtistInsert[]): Promise { const records = songArtists.filter( diff --git a/lib/supabase/storage/uploadFileByKey.ts b/lib/supabase/storage/uploadFileByKey.ts index ba146fa3..ae149173 100644 --- a/lib/supabase/storage/uploadFileByKey.ts +++ b/lib/supabase/storage/uploadFileByKey.ts @@ -3,6 +3,12 @@ import { SUPABASE_STORAGE_BUCKET } from "@/lib/const"; /** * Upload file to Supabase storage by key + * + * @param key + * @param file + * @param options + * @param options.contentType + * @param options.upsert */ export async function uploadFileByKey( key: string, diff --git a/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts b/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts index 60d38a96..c6082f98 100644 --- a/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts +++ b/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts @@ -1,6 +1,9 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { enrichTaskWithTriggerInfo } from "../enrichTaskWithTriggerInfo"; +import { fetchTriggerRuns } from "@/lib/trigger/fetchTriggerRuns"; +import { retrieveTaskRun } from "@/lib/trigger/retrieveTaskRun"; + vi.mock("@/lib/trigger/fetchTriggerRuns", () => ({ fetchTriggerRuns: vi.fn(), })); @@ -9,9 +12,6 @@ vi.mock("@/lib/trigger/retrieveTaskRun", () => ({ retrieveTaskRun: vi.fn(), })); -import { fetchTriggerRuns } from "@/lib/trigger/fetchTriggerRuns"; -import { retrieveTaskRun } from "@/lib/trigger/retrieveTaskRun"; - const mockTask = { id: "task-123", title: "Test Task", diff --git a/lib/tasks/__tests__/getTaskRunHandler.test.ts b/lib/tasks/__tests__/getTaskRunHandler.test.ts index 9f17fffc..3ab107f8 100644 --- a/lib/tasks/__tests__/getTaskRunHandler.test.ts +++ b/lib/tasks/__tests__/getTaskRunHandler.test.ts @@ -23,6 +23,9 @@ vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => ({ "Access-Control-Allow-Origin": "*" })), })); +/** + * + */ function createMockRequest(): NextRequest { return { url: "http://localhost:3000/api/tasks/runs", diff --git a/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts b/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts index f7126175..77d410da 100644 --- a/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts +++ b/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts @@ -24,6 +24,8 @@ vi.mock("@/lib/admins/checkIsAdmin", () => ({ /** * Creates a mock NextRequest with the given URL. + * + * @param url */ function createMockRequest(url: string): NextRequest { return { diff --git a/lib/tasks/__tests__/validateGetTasksQuery.test.ts b/lib/tasks/__tests__/validateGetTasksQuery.test.ts index b9d0dda7..11226d30 100644 --- a/lib/tasks/__tests__/validateGetTasksQuery.test.ts +++ b/lib/tasks/__tests__/validateGetTasksQuery.test.ts @@ -22,6 +22,10 @@ vi.mock("@/lib/admins/checkIsAdmin", () => ({ checkIsAdmin: vi.fn(), })); +/** + * + * @param url + */ function createMockRequest(url: string): NextRequest { return { url, diff --git a/lib/transcribe/processAudioTranscription.ts b/lib/transcribe/processAudioTranscription.ts index 351eee34..0e05905a 100644 --- a/lib/transcribe/processAudioTranscription.ts +++ b/lib/transcribe/processAudioTranscription.ts @@ -7,6 +7,8 @@ import { ProcessTranscriptionParams, ProcessTranscriptionResult } from "./types" /** * Fetches audio from URL, transcribes it with OpenAI Whisper, and saves both * the original audio and transcript markdown to the customer's files. + * + * @param params */ export async function processAudioTranscription( params: ProcessTranscriptionParams, @@ -64,6 +66,10 @@ export async function processAudioTranscription( }; } +/** + * + * @param contentType + */ function getExtensionFromContentType(contentType: string): string { if (contentType.includes("wav")) return "wav"; if (contentType.includes("m4a") || contentType.includes("mp4")) return "m4a"; diff --git a/lib/transcribe/saveAudioToFiles.ts b/lib/transcribe/saveAudioToFiles.ts index 12bda1ef..2124e512 100644 --- a/lib/transcribe/saveAudioToFiles.ts +++ b/lib/transcribe/saveAudioToFiles.ts @@ -2,6 +2,10 @@ import { uploadFileByKey } from "@/lib/supabase/storage/uploadFileByKey"; import { createFileRecord } from "@/lib/supabase/files/createFileRecord"; import { SaveAudioParams, FileRecord } from "./types"; +/** + * + * @param params + */ export async function saveAudioToFiles(params: SaveAudioParams): Promise { const { audioBlob, diff --git a/lib/transcribe/saveTranscriptToFiles.ts b/lib/transcribe/saveTranscriptToFiles.ts index 627feb6d..fa7518c5 100644 --- a/lib/transcribe/saveTranscriptToFiles.ts +++ b/lib/transcribe/saveTranscriptToFiles.ts @@ -2,6 +2,10 @@ import { uploadFileByKey } from "@/lib/supabase/storage/uploadFileByKey"; import { createFileRecord } from "@/lib/supabase/files/createFileRecord"; import { SaveTranscriptParams, FileRecord } from "./types"; +/** + * + * @param params + */ export async function saveTranscriptToFiles(params: SaveTranscriptParams): Promise { const { markdown, ownerAccountId, artistAccountId, title = "Transcription" } = params; diff --git a/lib/transcribe/types.ts b/lib/transcribe/types.ts index 91c0ac10..916e699c 100644 --- a/lib/transcribe/types.ts +++ b/lib/transcribe/types.ts @@ -56,6 +56,8 @@ export interface ProcessTranscriptionResult { /** * Formats transcription errors into user-friendly messages. * Centralizes error message logic to avoid duplication. + * + * @param error */ export function formatTranscriptionError(error: unknown): { message: string; status: number } { const rawMessage = error instanceof Error ? error.message : "Transcription failed"; From 8227c5af8c25e9dad3335476e73be4e2c59ce2e9 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Wed, 8 Apr 2026 11:06:12 -0500 Subject: [PATCH 4/6] Revert "chore: merge test branch and fix formatting" This reverts commit 023643b173ce51d80e1c186f80177cd97f97a713. --- app/api/accounts/[id]/route.ts | 1 - app/api/admins/coding/slack/route.ts | 2 -- app/api/admins/privy/route.ts | 5 ----- app/api/chats/[id]/messages/trailing/route.ts | 4 ---- app/api/songs/analyze/presets/route.ts | 1 - app/api/transcribe/route.ts | 4 ---- .../__tests__/validateUpdateAccountRequest.test.ts | 4 ---- lib/accounts/validateUpdateAccountRequest.ts | 2 -- .../emails/__tests__/validateGetAdminEmailsQuery.test.ts | 4 ---- lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts | 4 ---- lib/admins/pr/getPrStatusHandler.ts | 2 -- lib/admins/privy/countNewAccounts.ts | 3 --- lib/admins/privy/fetchPrivyLogins.ts | 4 ---- lib/admins/privy/getCutoffMs.ts | 2 -- lib/admins/privy/getLatestVerifiedAt.ts | 2 -- lib/admins/privy/toMs.ts | 2 -- .../content/__tests__/extractMessageAttachments.test.ts | 4 +--- .../content/__tests__/handleContentAgentCallback.test.ts | 7 ------- lib/ai/getModel.ts | 1 - lib/ai/isEmbedModel.ts | 2 -- lib/artists/__tests__/createArtistPostHandler.test.ts | 5 ----- lib/artists/__tests__/validateCreateArtistBody.test.ts | 5 ----- lib/auth/__tests__/validateAuthContext.test.ts | 4 ---- lib/catalog/formatCatalogSongsAsCSV.ts | 2 -- lib/catalog/getCatalogDataAsCSV.ts | 2 -- lib/catalog/getCatalogSongs.ts | 7 ------- lib/catalog/getCatalogs.ts | 4 ---- lib/chat/__tests__/integration/chatEndToEnd.test.ts | 5 ----- lib/chat/toolChains/getPrepareStepResult.ts | 2 -- lib/chats/__tests__/createChatHandler.test.ts | 4 ---- lib/chats/processCompactChatRequest.ts | 3 --- lib/coding-agent/__tests__/handleGitHubWebhook.test.ts | 6 ------ .../__tests__/onMergeTestToMainAction.test.ts | 3 --- lib/coding-agent/encodeGitHubThreadId.ts | 2 -- lib/coding-agent/handleMergeSuccess.ts | 2 -- lib/coding-agent/parseMergeActionId.ts | 2 -- lib/coding-agent/parseMergeTestToMainActionId.ts | 2 -- lib/composio/getCallbackUrl.ts | 1 - lib/content/__tests__/validateCreateContentBody.test.ts | 4 ---- lib/content/getArtistContentReadiness.ts | 5 ----- lib/content/getArtistFileTree.ts | 3 --- lib/content/getArtistRootPrefix.ts | 5 ----- lib/content/getContentValidateHandler.ts | 2 -- lib/content/isCompletedRun.ts | 4 ---- lib/content/persistCreateContentRunVideo.ts | 2 -- lib/content/validateGetContentEstimateQuery.ts | 2 -- lib/content/validateGetContentValidateQuery.ts | 2 -- lib/credits/getCreditUsage.ts | 1 - lib/credits/handleChatCredits.ts | 4 ---- lib/emails/processAndSendEmail.ts | 2 -- lib/evals/callChatFunctions.ts | 1 - lib/evals/callChatFunctionsWithResult.ts | 2 -- lib/evals/createToolsCalledScorer.ts | 3 --- lib/evals/extractTextFromResult.ts | 2 -- lib/evals/extractTextResultFromSteps.ts | 2 -- lib/evals/getCatalogSongsCountExpected.ts | 3 --- lib/evals/getSpotifyFollowersExpected.ts | 4 ---- lib/evals/scorers/CatalogAvailability.ts | 5 ----- lib/evals/scorers/QuestionAnswered.ts | 5 ----- lib/evals/scorers/ToolsCalled.ts | 8 -------- lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts | 3 --- lib/flamingo/getFlamingoPresetsHandler.ts | 1 - lib/github/__tests__/createOrUpdateFileContent.test.ts | 4 ++-- lib/github/expandSubmoduleEntries.ts | 6 ------ lib/github/getRepoGitModules.ts | 3 --- lib/github/resolveSubmodulePath.ts | 2 -- lib/mcp/resolveAccountId.ts | 2 -- lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts | 4 ---- .../__tests__/createNotificationHandler.test.ts | 4 ---- .../__tests__/validateCreateNotificationBody.test.ts | 5 ----- lib/prompts/getSystemPrompt.ts | 1 - lib/slack/getBotChannels.ts | 2 -- lib/slack/getBotUserId.ts | 2 -- lib/slack/getSlackUserInfo.ts | 3 --- lib/spotify/getSpotifyFollowers.ts | 1 - lib/supabase/account_artist_ids/getAccountArtistIds.ts | 4 +--- .../account_workspace_ids/getAccountWorkspaceIds.ts | 2 +- lib/supabase/files/createFileRecord.ts | 2 -- lib/supabase/song_artists/insertSongArtists.ts | 2 -- lib/supabase/storage/uploadFileByKey.ts | 6 ------ lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts | 6 +++--- lib/tasks/__tests__/getTaskRunHandler.test.ts | 3 --- lib/tasks/__tests__/validateGetTaskRunQuery.test.ts | 2 -- lib/tasks/__tests__/validateGetTasksQuery.test.ts | 4 ---- lib/transcribe/processAudioTranscription.ts | 6 ------ lib/transcribe/saveAudioToFiles.ts | 4 ---- lib/transcribe/saveTranscriptToFiles.ts | 4 ---- lib/transcribe/types.ts | 2 -- 88 files changed, 8 insertions(+), 274 deletions(-) diff --git a/app/api/accounts/[id]/route.ts b/app/api/accounts/[id]/route.ts index f6d7ace4..b272465a 100644 --- a/app/api/accounts/[id]/route.ts +++ b/app/api/accounts/[id]/route.ts @@ -25,7 +25,6 @@ export async function OPTIONS() { * - id (required): The unique identifier of the account (UUID) * * @param request - The request object - * @param params.params * @param params - Route params containing the account ID * @returns A NextResponse with account data */ diff --git a/app/api/admins/coding/slack/route.ts b/app/api/admins/coding/slack/route.ts index 956d7b4e..ea880d30 100644 --- a/app/api/admins/coding/slack/route.ts +++ b/app/api/admins/coding/slack/route.ts @@ -9,8 +9,6 @@ import { getSlackTagsHandler } from "@/lib/admins/slack/getSlackTagsHandler"; * Pulls directly from the Slack API as the source of truth. * Supports period filtering: all (default), daily, weekly, monthly. * Requires admin authentication. - * - * @param request */ export async function GET(request: NextRequest): Promise { return getSlackTagsHandler(request); diff --git a/app/api/admins/privy/route.ts b/app/api/admins/privy/route.ts index d22ec616..073bac60 100644 --- a/app/api/admins/privy/route.ts +++ b/app/api/admins/privy/route.ts @@ -8,16 +8,11 @@ import { getPrivyLoginsHandler } from "@/lib/admins/privy/getPrivyLoginsHandler" * Returns Privy login statistics for the requested time period. * Supports daily (last 24h), weekly (last 7 days), and monthly (last 30 days) periods. * Requires admin authentication. - * - * @param request */ export async function GET(request: NextRequest): Promise { return getPrivyLoginsHandler(request); } -/** - * - */ export async function OPTIONS(): Promise { return new NextResponse(null, { status: 204, headers: getCorsHeaders() }); } diff --git a/app/api/chats/[id]/messages/trailing/route.ts b/app/api/chats/[id]/messages/trailing/route.ts index 883ba4cc..afe9b673 100644 --- a/app/api/chats/[id]/messages/trailing/route.ts +++ b/app/api/chats/[id]/messages/trailing/route.ts @@ -17,10 +17,6 @@ export async function OPTIONS() { * DELETE /api/chats/[id]/messages/trailing * * Deletes all messages in chat `id` from `from_message_id` onward. - * - * @param request - * @param root0 - * @param root0.params */ export async function DELETE( request: NextRequest, diff --git a/app/api/songs/analyze/presets/route.ts b/app/api/songs/analyze/presets/route.ts index b809394c..8baccd38 100644 --- a/app/api/songs/analyze/presets/route.ts +++ b/app/api/songs/analyze/presets/route.ts @@ -28,7 +28,6 @@ export async function OPTIONS() { * - status: "success" * - presets: Array of { name, label, description, requiresAudio, responseFormat } * - * @param request * @returns A NextResponse with the list of available presets */ export async function GET(request: NextRequest): Promise { diff --git a/app/api/transcribe/route.ts b/app/api/transcribe/route.ts index 0896806b..28cf4261 100644 --- a/app/api/transcribe/route.ts +++ b/app/api/transcribe/route.ts @@ -2,10 +2,6 @@ import { NextRequest, NextResponse } from "next/server"; import { processAudioTranscription } from "@/lib/transcribe/processAudioTranscription"; import { formatTranscriptionError } from "@/lib/transcribe/types"; -/** - * - * @param req - */ export async function POST(req: NextRequest) { try { const body = await req.json(); diff --git a/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts b/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts index 581723cc..17f350aa 100644 --- a/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts +++ b/lib/accounts/__tests__/validateUpdateAccountRequest.test.ts @@ -16,10 +16,6 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); -/** - * - * @param body - */ function createRequest(body: unknown): NextRequest { return new NextRequest("http://localhost/api/accounts", { method: "PATCH", diff --git a/lib/accounts/validateUpdateAccountRequest.ts b/lib/accounts/validateUpdateAccountRequest.ts index d72667a6..78e66767 100644 --- a/lib/accounts/validateUpdateAccountRequest.ts +++ b/lib/accounts/validateUpdateAccountRequest.ts @@ -39,8 +39,6 @@ export type ValidatedUpdateAccountRequest = Omit< /** * Validates PATCH /api/accounts including auth, account override access, and body schema. - * - * @param request */ export async function validateUpdateAccountRequest( request: NextRequest, diff --git a/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts b/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts index 7531a477..90e1a3d0 100644 --- a/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts +++ b/lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts @@ -12,10 +12,6 @@ vi.mock("@/lib/admins/validateAdminAuth", () => ({ validateAdminAuth: vi.fn(), })); -/** - * - * @param url - */ function createMockRequest(url: string): NextRequest { return { url, diff --git a/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts b/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts index 826b69d6..e007e9c8 100644 --- a/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts +++ b/lib/admins/pr/__tests__/getPrMergedStatusHandler.test.ts @@ -19,10 +19,6 @@ vi.mock("@/lib/github/fetchGithubPrStatus", () => ({ const PR_URL_1 = "https://github.com/recoupable/api/pull/42"; const PR_URL_2 = "https://github.com/recoupable/chat/pull/100"; -/** - * - * @param urls - */ function makeRequest(urls: string[] = [PR_URL_1]) { const params = new URLSearchParams(); urls.forEach(url => params.append("pull_requests", url)); diff --git a/lib/admins/pr/getPrStatusHandler.ts b/lib/admins/pr/getPrStatusHandler.ts index 73cefa94..27081718 100644 --- a/lib/admins/pr/getPrStatusHandler.ts +++ b/lib/admins/pr/getPrStatusHandler.ts @@ -10,8 +10,6 @@ import { fetchGithubPrStatus } from "@/lib/github/fetchGithubPrStatus"; * Uses the GitHub REST API to check each PR's state. * * Requires admin authentication. - * - * @param request */ export async function getPrStatusHandler(request: NextRequest): Promise { try { diff --git a/lib/admins/privy/countNewAccounts.ts b/lib/admins/privy/countNewAccounts.ts index 1d34a14a..012ced53 100644 --- a/lib/admins/privy/countNewAccounts.ts +++ b/lib/admins/privy/countNewAccounts.ts @@ -5,9 +5,6 @@ import { getCutoffMs } from "./getCutoffMs"; /** * Counts how many users in the list were created within the cutoff period. - * - * @param users - * @param period */ export function countNewAccounts(users: User[], period: PrivyLoginsPeriod): number { const cutoffMs = getCutoffMs(period); diff --git a/lib/admins/privy/fetchPrivyLogins.ts b/lib/admins/privy/fetchPrivyLogins.ts index 35ac556c..ae4d4dd0 100644 --- a/lib/admins/privy/fetchPrivyLogins.ts +++ b/lib/admins/privy/fetchPrivyLogins.ts @@ -20,10 +20,6 @@ export type FetchPrivyLoginsResult = { totalPrivyUsers: number; }; -/** - * - * @param period - */ export async function fetchPrivyLogins(period: PrivyLoginsPeriod): Promise { const isAll = period === "all"; const cutoffMs = getCutoffMs(period); diff --git a/lib/admins/privy/getCutoffMs.ts b/lib/admins/privy/getCutoffMs.ts index 4de0fa32..8b80ec6a 100644 --- a/lib/admins/privy/getCutoffMs.ts +++ b/lib/admins/privy/getCutoffMs.ts @@ -5,8 +5,6 @@ import { PERIOD_DAYS } from "./periodDays"; * Returns the cutoff timestamp in milliseconds for a given period. * Uses midnight UTC calendar day boundaries to match Privy dashboard behavior. * Returns 0 for "all" (no cutoff). - * - * @param period */ export function getCutoffMs(period: PrivyLoginsPeriod): number { if (period === "all") return 0; diff --git a/lib/admins/privy/getLatestVerifiedAt.ts b/lib/admins/privy/getLatestVerifiedAt.ts index c7f7ba9b..465ea876 100644 --- a/lib/admins/privy/getLatestVerifiedAt.ts +++ b/lib/admins/privy/getLatestVerifiedAt.ts @@ -4,8 +4,6 @@ import type { User } from "@privy-io/node"; /** * Returns the most recent latest_verified_at (in ms) across all linked_accounts for a Privy user. * Returns null if no linked account has a latest_verified_at. - * - * @param user */ export function getLatestVerifiedAt(user: User): number | null { const linkedAccounts = user.linked_accounts; diff --git a/lib/admins/privy/toMs.ts b/lib/admins/privy/toMs.ts index 2daad687..472ff9eb 100644 --- a/lib/admins/privy/toMs.ts +++ b/lib/admins/privy/toMs.ts @@ -1,8 +1,6 @@ /** * Normalizes a Privy timestamp to milliseconds. * Privy docs say milliseconds but examples show seconds (10 digits). - * - * @param timestamp */ export function toMs(timestamp: number): number { return timestamp > 1e12 ? timestamp : timestamp * 1000; diff --git a/lib/agents/content/__tests__/extractMessageAttachments.test.ts b/lib/agents/content/__tests__/extractMessageAttachments.test.ts index 4dee2308..61f4ba89 100644 --- a/lib/agents/content/__tests__/extractMessageAttachments.test.ts +++ b/lib/agents/content/__tests__/extractMessageAttachments.test.ts @@ -69,9 +69,7 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); - expect(result.imageUrls).toContain( - "https://blob.vercel-storage.com/content-attachments/face.png", - ); + expect(result.imageUrls).toContain("https://blob.vercel-storage.com/content-attachments/face.png"); expect(result.songUrl).toBeNull(); }); diff --git a/lib/agents/content/__tests__/handleContentAgentCallback.test.ts b/lib/agents/content/__tests__/handleContentAgentCallback.test.ts index 5edf71a3..36fa4ea1 100644 --- a/lib/agents/content/__tests__/handleContentAgentCallback.test.ts +++ b/lib/agents/content/__tests__/handleContentAgentCallback.test.ts @@ -84,10 +84,6 @@ describe("handleContentAgentCallback", () => { }); describe("completed callback with videos", () => { - /** - * - * @param body - */ function makeAuthRequest(body: object) { return new Request("http://localhost/api/content-agent/callback", { method: "POST", @@ -96,9 +92,6 @@ describe("handleContentAgentCallback", () => { }); } - /** - * - */ function mockThread() { const thread = { post: vi.fn().mockResolvedValue(undefined), diff --git a/lib/ai/getModel.ts b/lib/ai/getModel.ts index 99ca9c2f..edf4d425 100644 --- a/lib/ai/getModel.ts +++ b/lib/ai/getModel.ts @@ -3,7 +3,6 @@ import { GatewayLanguageModelEntry } from "@ai-sdk/gateway"; /** * Returns a specific model by its ID from the list of available models. - * * @param modelId - The ID of the model to find * @returns The matching model or undefined if not found */ diff --git a/lib/ai/isEmbedModel.ts b/lib/ai/isEmbedModel.ts index 4901f1e8..7c5fbbfb 100644 --- a/lib/ai/isEmbedModel.ts +++ b/lib/ai/isEmbedModel.ts @@ -3,8 +3,6 @@ import { GatewayLanguageModelEntry } from "@ai-sdk/gateway"; /** * Determines if a model is an embedding model (not suitable for chat). * Embed models typically have 0 output pricing since they only produce embeddings. - * - * @param m */ export const isEmbedModel = (m: GatewayLanguageModelEntry): boolean => { const pricing = m.pricing; diff --git a/lib/artists/__tests__/createArtistPostHandler.test.ts b/lib/artists/__tests__/createArtistPostHandler.test.ts index dd72b2e1..e63d244d 100644 --- a/lib/artists/__tests__/createArtistPostHandler.test.ts +++ b/lib/artists/__tests__/createArtistPostHandler.test.ts @@ -14,11 +14,6 @@ vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: (...args: unknown[]) => mockValidateAuthContext(...args), })); -/** - * - * @param body - * @param headers - */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json", diff --git a/lib/artists/__tests__/validateCreateArtistBody.test.ts b/lib/artists/__tests__/validateCreateArtistBody.test.ts index d12fe1ba..4de5562b 100644 --- a/lib/artists/__tests__/validateCreateArtistBody.test.ts +++ b/lib/artists/__tests__/validateCreateArtistBody.test.ts @@ -9,11 +9,6 @@ vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: (...args: unknown[]) => mockValidateAuthContext(...args), })); -/** - * - * @param body - * @param headers - */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json" }; return new NextRequest("http://localhost/api/artists", { diff --git a/lib/auth/__tests__/validateAuthContext.test.ts b/lib/auth/__tests__/validateAuthContext.test.ts index c4769178..31dda345 100644 --- a/lib/auth/__tests__/validateAuthContext.test.ts +++ b/lib/auth/__tests__/validateAuthContext.test.ts @@ -33,10 +33,6 @@ const mockGetAuthenticatedAccountId = vi.mocked(getAuthenticatedAccountId); const mockValidateOrganizationAccess = vi.mocked(validateOrganizationAccess); const mockCanAccessAccount = vi.mocked(canAccessAccount); -/** - * - * @param headers - */ function createMockRequest(headers: Record = {}): Request { return { headers: { diff --git a/lib/catalog/formatCatalogSongsAsCSV.ts b/lib/catalog/formatCatalogSongsAsCSV.ts index 29cc443c..5115eece 100644 --- a/lib/catalog/formatCatalogSongsAsCSV.ts +++ b/lib/catalog/formatCatalogSongsAsCSV.ts @@ -2,8 +2,6 @@ import { CatalogSong } from "./getCatalogSongs"; /** * Formats catalog songs into the CSV-like format expected by the scorer - * - * @param songs */ export function formatCatalogSongsAsCSV(songs: CatalogSong[]): string { const csvLines = songs.map(song => { diff --git a/lib/catalog/getCatalogDataAsCSV.ts b/lib/catalog/getCatalogDataAsCSV.ts index 4a86fc0e..ea529c37 100644 --- a/lib/catalog/getCatalogDataAsCSV.ts +++ b/lib/catalog/getCatalogDataAsCSV.ts @@ -3,8 +3,6 @@ import { formatCatalogSongsAsCSV } from "./formatCatalogSongsAsCSV"; /** * Gets all catalog songs and formats them as CSV for the scorer - * - * @param catalogId */ export async function getCatalogDataAsCSV(catalogId: string): Promise { const allSongs: CatalogSong[] = []; diff --git a/lib/catalog/getCatalogSongs.ts b/lib/catalog/getCatalogSongs.ts index d7b5ca62..c58c33be 100644 --- a/lib/catalog/getCatalogSongs.ts +++ b/lib/catalog/getCatalogSongs.ts @@ -25,13 +25,6 @@ export interface CatalogSongsResponse { error?: string; } -/** - * - * @param catalogId - * @param pageSize - * @param page - * @param artistName - */ export async function getCatalogSongs( catalogId: string, pageSize: number = 100, diff --git a/lib/catalog/getCatalogs.ts b/lib/catalog/getCatalogs.ts index 4ac8a842..9533183b 100644 --- a/lib/catalog/getCatalogs.ts +++ b/lib/catalog/getCatalogs.ts @@ -8,10 +8,6 @@ export interface CatalogsResponse { error?: string; } -/** - * - * @param accountId - */ export async function getCatalogs(accountId: string): Promise { try { const response = await fetch( diff --git a/lib/chat/__tests__/integration/chatEndToEnd.test.ts b/lib/chat/__tests__/integration/chatEndToEnd.test.ts index f2aaccad..b54e51f5 100644 --- a/lib/chat/__tests__/integration/chatEndToEnd.test.ts +++ b/lib/chat/__tests__/integration/chatEndToEnd.test.ts @@ -154,11 +154,6 @@ const mockDeductCredits = vi.mocked(deductCredits); const mockGenerateChatTitle = vi.mocked(generateChatTitle); // Helper to create mock NextRequest -/** - * - * @param body - * @param headers - */ function createMockRequest(body: unknown, headers: Record = {}): Request { return { json: () => Promise.resolve(body), diff --git a/lib/chat/toolChains/getPrepareStepResult.ts b/lib/chat/toolChains/getPrepareStepResult.ts index c011c078..02dd8e71 100644 --- a/lib/chat/toolChains/getPrepareStepResult.ts +++ b/lib/chat/toolChains/getPrepareStepResult.ts @@ -12,8 +12,6 @@ type PrepareStepOptions = { /** * Returns the next tool to run based on timeline progression through tool chains. * Uses toolCallsContent to track exact execution order and position in sequence. - * - * @param options */ const getPrepareStepResult = (options: PrepareStepOptions): PrepareStepResult | undefined => { const { steps } = options; diff --git a/lib/chats/__tests__/createChatHandler.test.ts b/lib/chats/__tests__/createChatHandler.test.ts index 3258d6cf..6d509147 100644 --- a/lib/chats/__tests__/createChatHandler.test.ts +++ b/lib/chats/__tests__/createChatHandler.test.ts @@ -41,10 +41,6 @@ vi.mock("../generateChatTitle", () => ({ generateChatTitle: vi.fn(), })); -/** - * - * @param headers - */ function createMockRequest( headers: Record = { "x-api-key": "test-api-key" }, ): NextRequest { diff --git a/lib/chats/processCompactChatRequest.ts b/lib/chats/processCompactChatRequest.ts index c98c2e97..a1699c93 100644 --- a/lib/chats/processCompactChatRequest.ts +++ b/lib/chats/processCompactChatRequest.ts @@ -17,9 +17,6 @@ interface ProcessCompactChatRequestParams { * Verifies the chat exists and the user has access before compacting. * * @param params - The parameters for processing the chat compaction. - * @param params.chatId - * @param params.prompt - * @param params.accountId * @returns The result of the compaction attempt. */ export async function processCompactChatRequest({ diff --git a/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts b/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts index 194a7170..5e059f4e 100644 --- a/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts +++ b/lib/coding-agent/__tests__/handleGitHubWebhook.test.ts @@ -45,12 +45,6 @@ const BASE_PAYLOAD = { }, }; -/** - * - * @param body - * @param event - * @param signature - */ function makeRequest(body: unknown, event = "issue_comment", signature = "valid") { return { text: () => Promise.resolve(JSON.stringify(body)), diff --git a/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts b/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts index f173d6ce..8af470e1 100644 --- a/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts +++ b/lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts @@ -12,9 +12,6 @@ beforeEach(() => { process.env.GITHUB_TOKEN = "ghp_test"; }); -/** - * - */ function createMockBot() { return { onAction: vi.fn() } as any; } diff --git a/lib/coding-agent/encodeGitHubThreadId.ts b/lib/coding-agent/encodeGitHubThreadId.ts index f4797e43..1cfff2fe 100644 --- a/lib/coding-agent/encodeGitHubThreadId.ts +++ b/lib/coding-agent/encodeGitHubThreadId.ts @@ -6,8 +6,6 @@ import type { GitHubThreadId } from "@chat-adapter/github"; * * - PR-level: `github:{owner}/{repo}:{prNumber}` * - Review comment: `github:{owner}/{repo}:{prNumber}:rc:{reviewCommentId}` - * - * @param thread */ export function encodeGitHubThreadId(thread: GitHubThreadId): string { const { owner, repo, prNumber, reviewCommentId } = thread; diff --git a/lib/coding-agent/handleMergeSuccess.ts b/lib/coding-agent/handleMergeSuccess.ts index c241923b..f026f48d 100644 --- a/lib/coding-agent/handleMergeSuccess.ts +++ b/lib/coding-agent/handleMergeSuccess.ts @@ -7,8 +7,6 @@ import type { CodingAgentThreadState } from "./types"; * Handles post-merge cleanup after all PRs merged successfully. * Deletes the shared PR state keys for all repos and persists the latest * snapshot via upsertAccountSnapshot. - * - * @param state */ export async function handleMergeSuccess(state: CodingAgentThreadState): Promise { try { diff --git a/lib/coding-agent/parseMergeActionId.ts b/lib/coding-agent/parseMergeActionId.ts index 25fd3eeb..5118249e 100644 --- a/lib/coding-agent/parseMergeActionId.ts +++ b/lib/coding-agent/parseMergeActionId.ts @@ -1,8 +1,6 @@ /** * Parses a merge action ID like "merge_pr:recoupable/api#42" * into { repo, number } or null if the format doesn't match. - * - * @param actionId */ export function parseMergeActionId(actionId: string) { const match = actionId.match(/^merge_pr:(.+)#(\d+)$/); diff --git a/lib/coding-agent/parseMergeTestToMainActionId.ts b/lib/coding-agent/parseMergeTestToMainActionId.ts index 14133eac..1228615f 100644 --- a/lib/coding-agent/parseMergeTestToMainActionId.ts +++ b/lib/coding-agent/parseMergeTestToMainActionId.ts @@ -1,8 +1,6 @@ /** * Parses a merge_test_to_main action ID like "merge_test_to_main:recoupable/api" * into the repo string, or null if the format doesn't match. - * - * @param actionId */ export function parseMergeTestToMainActionId(actionId: string): string | null { const prefix = "merge_test_to_main:"; diff --git a/lib/composio/getCallbackUrl.ts b/lib/composio/getCallbackUrl.ts index 8c83505a..570c9251 100644 --- a/lib/composio/getCallbackUrl.ts +++ b/lib/composio/getCallbackUrl.ts @@ -19,7 +19,6 @@ interface CallbackOptions { * * @param options.destination - Where to redirect: "chat" or "connectors" * @param options.roomId - For chat destination, the room ID to return to - * @param options * @returns Full callback URL with success indicator */ export function getCallbackUrl(options: CallbackOptions): string { diff --git a/lib/content/__tests__/validateCreateContentBody.test.ts b/lib/content/__tests__/validateCreateContentBody.test.ts index 31b1c461..1a71d5ae 100644 --- a/lib/content/__tests__/validateCreateContentBody.test.ts +++ b/lib/content/__tests__/validateCreateContentBody.test.ts @@ -20,10 +20,6 @@ vi.mock("@/lib/content/resolveArtistSlug", () => ({ resolveArtistSlug: vi.fn().mockResolvedValue("gatsby-grace"), })); -/** - * - * @param body - */ function createRequest(body: unknown): NextRequest { return new NextRequest("http://localhost/api/content/create", { method: "POST", diff --git a/lib/content/getArtistContentReadiness.ts b/lib/content/getArtistContentReadiness.ts index 9238598e..a902ce0f 100644 --- a/lib/content/getArtistContentReadiness.ts +++ b/lib/content/getArtistContentReadiness.ts @@ -22,11 +22,6 @@ export interface ArtistContentReadiness { /** * Checks whether an artist has the expected files for content creation. * Searches the main repo and org submodule repos. - * - * @param root0 - * @param root0.accountId - * @param root0.artistAccountId - * @param root0.artistSlug */ export async function getArtistContentReadiness({ accountId, diff --git a/lib/content/getArtistFileTree.ts b/lib/content/getArtistFileTree.ts index b5392b52..908855a0 100644 --- a/lib/content/getArtistFileTree.ts +++ b/lib/content/getArtistFileTree.ts @@ -4,9 +4,6 @@ import { getOrgRepoUrls } from "@/lib/github/getOrgRepoUrls"; /** * Gets the file tree that contains the artist, checking the main repo * first, then falling back to org submodule repos. - * - * @param githubRepo - * @param artistSlug */ export async function getArtistFileTree( githubRepo: string, diff --git a/lib/content/getArtistRootPrefix.ts b/lib/content/getArtistRootPrefix.ts index bf81d48a..5a777abe 100644 --- a/lib/content/getArtistRootPrefix.ts +++ b/lib/content/getArtistRootPrefix.ts @@ -1,8 +1,3 @@ -/** - * - * @param paths - * @param artistSlug - */ export function getArtistRootPrefix(paths: string[], artistSlug: string): string { const preferredPrefix = `artists/${artistSlug}/`; if (paths.some(path => path.startsWith(preferredPrefix))) { diff --git a/lib/content/getContentValidateHandler.ts b/lib/content/getContentValidateHandler.ts index 81cd0ce8..e0c758b8 100644 --- a/lib/content/getContentValidateHandler.ts +++ b/lib/content/getContentValidateHandler.ts @@ -8,8 +8,6 @@ import { getArtistContentReadiness } from "@/lib/content/getArtistContentReadine * Handler for GET /api/content/validate. * NOTE: Phase 1 returns structural readiness scaffolding. Deep filesystem checks * are performed in the background task before spend-heavy steps. - * - * @param request */ export async function getContentValidateHandler(request: NextRequest): Promise { const validated = await validateGetContentValidateQuery(request); diff --git a/lib/content/isCompletedRun.ts b/lib/content/isCompletedRun.ts index 951d20b2..855ea068 100644 --- a/lib/content/isCompletedRun.ts +++ b/lib/content/isCompletedRun.ts @@ -5,10 +5,6 @@ export type TriggerRunLike = { output?: unknown; }; -/** - * - * @param run - */ export function isCompletedRun(run: TriggerRunLike): boolean { return run.status === "COMPLETED"; } diff --git a/lib/content/persistCreateContentRunVideo.ts b/lib/content/persistCreateContentRunVideo.ts index 69bac792..25a77eed 100644 --- a/lib/content/persistCreateContentRunVideo.ts +++ b/lib/content/persistCreateContentRunVideo.ts @@ -27,8 +27,6 @@ type CreateContentOutput = { * and returns the run with normalized output. * * This keeps Supabase writes in API only. - * - * @param run */ export async function persistCreateContentRunVideo(run: T): Promise { if (run.taskIdentifier !== CREATE_CONTENT_TASK_ID || !isCompletedRun(run)) { diff --git a/lib/content/validateGetContentEstimateQuery.ts b/lib/content/validateGetContentEstimateQuery.ts index 97af7468..5828e7cc 100644 --- a/lib/content/validateGetContentEstimateQuery.ts +++ b/lib/content/validateGetContentEstimateQuery.ts @@ -15,8 +15,6 @@ export type ValidatedGetContentEstimateQuery = z.infer { diff --git a/lib/evals/callChatFunctionsWithResult.ts b/lib/evals/callChatFunctionsWithResult.ts index b80fcb58..a792248b 100644 --- a/lib/evals/callChatFunctionsWithResult.ts +++ b/lib/evals/callChatFunctionsWithResult.ts @@ -8,8 +8,6 @@ import { ChatRequestBody } from "@/lib/chat/validateChatRequest"; * * Note: result.toolCalls only contains calls from the LAST step. When using multi-step * tool chains, we need to collect toolCalls from result.steps to capture all tool usage. - * - * @param input */ export async function callChatFunctionsWithResult(input: string) { const messages: UIMessage[] = [ diff --git a/lib/evals/createToolsCalledScorer.ts b/lib/evals/createToolsCalledScorer.ts index 8a9ac7e7..1d838ee3 100644 --- a/lib/evals/createToolsCalledScorer.ts +++ b/lib/evals/createToolsCalledScorer.ts @@ -3,9 +3,6 @@ import { ToolsCalled } from "./scorers/ToolsCalled"; /** * Creates a scorer that checks if required tools were called. * Handles extracting output text and toolCalls from the task result. - * - * @param requiredTools - * @param penalizedTools */ export const createToolsCalledScorer = (requiredTools: string[], penalizedTools: string[] = []) => { return async (args: { output: unknown; expected?: string; input: string }) => { diff --git a/lib/evals/extractTextFromResult.ts b/lib/evals/extractTextFromResult.ts index dc67f3ab..fac24cf6 100644 --- a/lib/evals/extractTextFromResult.ts +++ b/lib/evals/extractTextFromResult.ts @@ -3,8 +3,6 @@ import { extractTextResultFromSteps } from "./extractTextResultFromSteps"; /** * Extract text from a GenerateTextResult - * - * @param result */ export function extractTextFromResult(result: Awaited>): string { // Handle multi-step responses (when maxSteps > 1) diff --git a/lib/evals/extractTextResultFromSteps.ts b/lib/evals/extractTextResultFromSteps.ts index 16881677..44c0ae0d 100644 --- a/lib/evals/extractTextResultFromSteps.ts +++ b/lib/evals/extractTextResultFromSteps.ts @@ -4,8 +4,6 @@ import type { TextPart } from "ai"; /** * Extract text from multi-step GenerateTextResult * Handles responses where maxSteps > 1 - * - * @param result */ export function extractTextResultFromSteps( result: Awaited>, diff --git a/lib/evals/getCatalogSongsCountExpected.ts b/lib/evals/getCatalogSongsCountExpected.ts index d94383ef..6f04e59c 100644 --- a/lib/evals/getCatalogSongsCountExpected.ts +++ b/lib/evals/getCatalogSongsCountExpected.ts @@ -2,9 +2,6 @@ import { getCatalogs } from "@/lib/catalog/getCatalogs"; import { getCatalogSongs } from "@/lib/catalog/getCatalogSongs"; import { EVAL_ACCOUNT_ID } from "@/lib/consts"; -/** - * - */ async function getCatalogSongsCountExpected() { try { const catalogsData = await getCatalogs(EVAL_ACCOUNT_ID); diff --git a/lib/evals/getSpotifyFollowersExpected.ts b/lib/evals/getSpotifyFollowersExpected.ts index f5221937..ef96e248 100644 --- a/lib/evals/getSpotifyFollowersExpected.ts +++ b/lib/evals/getSpotifyFollowersExpected.ts @@ -1,9 +1,5 @@ import { getSpotifyFollowers } from "@/lib/spotify/getSpotifyFollowers"; -/** - * - * @param artist - */ async function getSpotifyFollowersExpected(artist: string) { try { const followerCount = await getSpotifyFollowers(artist); diff --git a/lib/evals/scorers/CatalogAvailability.ts b/lib/evals/scorers/CatalogAvailability.ts index 8cf292d9..f4829ea4 100644 --- a/lib/evals/scorers/CatalogAvailability.ts +++ b/lib/evals/scorers/CatalogAvailability.ts @@ -5,11 +5,6 @@ import { z } from "zod"; /** * Custom scorer that uses AI to check if recommended songs are actually in the catalog - * - * @param root0 - * @param root0.output - * @param root0.expected - * @param root0.input */ export const CatalogAvailability = async ({ output, diff --git a/lib/evals/scorers/QuestionAnswered.ts b/lib/evals/scorers/QuestionAnswered.ts index a7bafd1d..abe0222c 100644 --- a/lib/evals/scorers/QuestionAnswered.ts +++ b/lib/evals/scorers/QuestionAnswered.ts @@ -5,11 +5,6 @@ import { z } from "zod"; /** * Custom scorer that checks if the AI actually answered the customer's question * with a specific answer, or if it deflected/explained why it couldn't answer - * - * @param root0 - * @param root0.output - * @param root0.expected - * @param root0.input */ export const QuestionAnswered = async ({ output, diff --git a/lib/evals/scorers/ToolsCalled.ts b/lib/evals/scorers/ToolsCalled.ts index 6a451100..2d901ec3 100644 --- a/lib/evals/scorers/ToolsCalled.ts +++ b/lib/evals/scorers/ToolsCalled.ts @@ -1,13 +1,5 @@ /** * Generic scorer that checks if specific tools were called - * - * @param root0 - * @param root0.output - * @param root0.expected - * @param root0.input - * @param root0.toolCalls - * @param root0.requiredTools - * @param root0.penalizedTools */ export const ToolsCalled = async ({ toolCalls, diff --git a/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts b/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts index 1c30d8fc..19109b2d 100644 --- a/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts +++ b/lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts @@ -17,9 +17,6 @@ vi.mock("../presets", () => ({ getPresetSummaries: vi.fn(), })); -/** - * - */ function createMockRequest(): NextRequest { return { headers: new Headers({ "x-api-key": "test-key" }), diff --git a/lib/flamingo/getFlamingoPresetsHandler.ts b/lib/flamingo/getFlamingoPresetsHandler.ts index f33d491d..e35b5899 100644 --- a/lib/flamingo/getFlamingoPresetsHandler.ts +++ b/lib/flamingo/getFlamingoPresetsHandler.ts @@ -10,7 +10,6 @@ import { validateAuthContext } from "@/lib/auth/validateAuthContext"; * Returns a list of all available analysis presets. * Requires authentication via x-api-key header or Authorization bearer token. * - * @param request * @returns A NextResponse with the list of available presets. */ export async function getFlamingoPresetsHandler(request: NextRequest): Promise { diff --git a/lib/github/__tests__/createOrUpdateFileContent.test.ts b/lib/github/__tests__/createOrUpdateFileContent.test.ts index f8fee1a1..8e2a19a1 100644 --- a/lib/github/__tests__/createOrUpdateFileContent.test.ts +++ b/lib/github/__tests__/createOrUpdateFileContent.test.ts @@ -1,12 +1,12 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { createOrUpdateFileContent } from "../createOrUpdateFileContent"; -import { parseGitHubRepoUrl } from "../parseGitHubRepoUrl"; - vi.mock("../parseGitHubRepoUrl", () => ({ parseGitHubRepoUrl: vi.fn(), })); +import { parseGitHubRepoUrl } from "../parseGitHubRepoUrl"; + const mockFetch = vi.fn(); global.fetch = mockFetch; diff --git a/lib/github/expandSubmoduleEntries.ts b/lib/github/expandSubmoduleEntries.ts index 3082c63b..9531bee1 100644 --- a/lib/github/expandSubmoduleEntries.ts +++ b/lib/github/expandSubmoduleEntries.ts @@ -11,15 +11,9 @@ interface SubmoduleRef { * Resolves submodule URLs from .gitmodules, fetches each submodule's tree, * and merges the results into the regular entries with correct path prefixes. * - * @param regularEntries.regularEntries * @param regularEntries - Non-submodule file tree entries * @param submoduleEntries - Submodule references (type "commit" from GitHub Trees API) * @param repo - Repository context for fetching .gitmodules - * @param regularEntries.submoduleEntries - * @param regularEntries.repo - * @param regularEntries.repo.owner - * @param regularEntries.repo.repo - * @param regularEntries.repo.branch * @returns Combined file tree entries with submodules expanded as directories */ export async function expandSubmoduleEntries({ diff --git a/lib/github/getRepoGitModules.ts b/lib/github/getRepoGitModules.ts index 8913a6ae..caa0304e 100644 --- a/lib/github/getRepoGitModules.ts +++ b/lib/github/getRepoGitModules.ts @@ -4,12 +4,9 @@ import { parseGitModules, type SubmoduleEntry } from "./parseGitModules"; * Fetches and parses .gitmodules from a GitHub repository. * Uses the GitHub Contents API (works for both public and private repos). * - * @param owner.owner * @param owner - The GitHub repository owner * @param repo - The GitHub repository name * @param branch - The branch to fetch from - * @param owner.repo - * @param owner.branch * @returns Array of submodule entries, or null if .gitmodules doesn't exist or fetch fails */ export async function getRepoGitModules({ diff --git a/lib/github/resolveSubmodulePath.ts b/lib/github/resolveSubmodulePath.ts index 029f1b1d..7c3f60ed 100644 --- a/lib/github/resolveSubmodulePath.ts +++ b/lib/github/resolveSubmodulePath.ts @@ -6,10 +6,8 @@ import { getRepoGitModules } from "./getRepoGitModules"; * If the path falls within a submodule, returns the submodule's repo URL * and the relative path within it. Otherwise returns the original values. * - * @param githubRepo.githubRepo * @param githubRepo - The parent GitHub repository URL * @param path - The file path to resolve - * @param githubRepo.path * @returns The resolved repo URL and path */ export async function resolveSubmodulePath({ diff --git a/lib/mcp/resolveAccountId.ts b/lib/mcp/resolveAccountId.ts index 456fe4c6..03d1d0d8 100644 --- a/lib/mcp/resolveAccountId.ts +++ b/lib/mcp/resolveAccountId.ts @@ -16,8 +16,6 @@ export interface ResolveAccountIdResult { * Validates access when an org API key attempts to use an account_id override. * * @param params - The auth info and optional account_id override. - * @param params.authInfo - * @param params.accountIdOverride * @returns The resolved accountId or an error message. */ export async function resolveAccountId({ diff --git a/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts b/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts index d8a64f79..4942fdfb 100644 --- a/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts +++ b/lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts @@ -15,10 +15,6 @@ const transcribeAudioSchema = z.object({ type TranscribeAudioArgs = z.infer; -/** - * - * @param server - */ export function registerTranscribeAudioTool(server: McpServer): void { server.registerTool( "transcribe_audio", diff --git a/lib/notifications/__tests__/createNotificationHandler.test.ts b/lib/notifications/__tests__/createNotificationHandler.test.ts index 60b6e5ba..ca7fb677 100644 --- a/lib/notifications/__tests__/createNotificationHandler.test.ts +++ b/lib/notifications/__tests__/createNotificationHandler.test.ts @@ -26,10 +26,6 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); -/** - * - * @param body - */ function createRequest(body: unknown): NextRequest { return new NextRequest("https://recoup-api.vercel.app/api/notifications", { method: "POST", diff --git a/lib/notifications/__tests__/validateCreateNotificationBody.test.ts b/lib/notifications/__tests__/validateCreateNotificationBody.test.ts index 645ccedc..10390b15 100644 --- a/lib/notifications/__tests__/validateCreateNotificationBody.test.ts +++ b/lib/notifications/__tests__/validateCreateNotificationBody.test.ts @@ -16,11 +16,6 @@ vi.mock("@/lib/networking/safeParseJson", () => ({ safeParseJson: vi.fn(async (req: Request) => req.json()), })); -/** - * - * @param body - * @param headers - */ function createRequest(body: unknown, headers: Record = {}): NextRequest { const defaultHeaders: Record = { "Content-Type": "application/json" }; return new NextRequest("http://localhost/api/notifications", { diff --git a/lib/prompts/getSystemPrompt.ts b/lib/prompts/getSystemPrompt.ts index 5077609a..54964670 100644 --- a/lib/prompts/getSystemPrompt.ts +++ b/lib/prompts/getSystemPrompt.ts @@ -13,7 +13,6 @@ import { AccountWithDetails } from "@/lib/supabase/accounts/getAccountWithDetail * @param params.artistInstruction - The artist instruction * @param params.conversationName - The name of the conversation * @param params.accountWithDetails - The account with details - * @param params.orgId * @returns The system prompt */ export function getSystemPrompt({ diff --git a/lib/slack/getBotChannels.ts b/lib/slack/getBotChannels.ts index 6c2f905a..01fb47ff 100644 --- a/lib/slack/getBotChannels.ts +++ b/lib/slack/getBotChannels.ts @@ -9,8 +9,6 @@ interface ConversationsListResponse { /** * Returns all channels the bot is a member of, paginating through all results. - * - * @param token */ export async function getBotChannels(token: string): Promise> { const channels: Array<{ id: string; name: string }> = []; diff --git a/lib/slack/getBotUserId.ts b/lib/slack/getBotUserId.ts index 673ec465..1c3e0924 100644 --- a/lib/slack/getBotUserId.ts +++ b/lib/slack/getBotUserId.ts @@ -8,8 +8,6 @@ interface AuthTestResponse { /** * Returns the authenticated bot's Slack user ID via auth.test. - * - * @param token */ export async function getBotUserId(token: string): Promise { const authTest = await slackGet("auth.test", token); diff --git a/lib/slack/getSlackUserInfo.ts b/lib/slack/getSlackUserInfo.ts index 91873ddf..eb144e45 100644 --- a/lib/slack/getSlackUserInfo.ts +++ b/lib/slack/getSlackUserInfo.ts @@ -16,9 +16,6 @@ interface UsersInfoResponse { /** * Fetches a Slack account's display name and avatar by their Slack ID. - * - * @param token - * @param userId */ export async function getSlackUserInfo( token: string, diff --git a/lib/spotify/getSpotifyFollowers.ts b/lib/spotify/getSpotifyFollowers.ts index acd1c3be..235de41e 100644 --- a/lib/spotify/getSpotifyFollowers.ts +++ b/lib/spotify/getSpotifyFollowers.ts @@ -37,7 +37,6 @@ interface SpotifySearchResponse { /** * Get Spotify follower count for an artist - * * @param artistName - The name of the artist to search for * @returns Promise - The follower count of the first matching artist */ diff --git a/lib/supabase/account_artist_ids/getAccountArtistIds.ts b/lib/supabase/account_artist_ids/getAccountArtistIds.ts index 42b550d0..e4e6b809 100644 --- a/lib/supabase/account_artist_ids/getAccountArtistIds.ts +++ b/lib/supabase/account_artist_ids/getAccountArtistIds.ts @@ -8,9 +8,7 @@ export type AccountArtistRow = ArtistQueryRow & { artist_id: string; pinned: boo * Get all artists for an array of artist IDs or account IDs, with full info. * Returns raw data - formatting should be done by caller. * - * @param params - Object with artistIds or accountIds array - * @param params.artistIds - * @param params.accountIds + * @param params Object with artistIds or accountIds array * @returns Array of raw artist rows from database */ export async function getAccountArtistIds(params: { diff --git a/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts b/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts index 4ca7ad8e..ae121fdd 100644 --- a/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts +++ b/lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts @@ -10,7 +10,7 @@ export type AccountWorkspaceRow = Omit & { * Get all workspaces for an account, with full info. * Returns raw data - formatting should be done by caller. * - * @param accountId - The owner's account ID + * @param accountId The owner's account ID * @returns Array of raw workspace rows from database */ export async function getAccountWorkspaceIds(accountId: string): Promise { diff --git a/lib/supabase/files/createFileRecord.ts b/lib/supabase/files/createFileRecord.ts index 3182de11..6f836f3c 100644 --- a/lib/supabase/files/createFileRecord.ts +++ b/lib/supabase/files/createFileRecord.ts @@ -25,8 +25,6 @@ export interface CreateFileRecordParams { /** * Create a file record in the database - * - * @param params */ export async function createFileRecord(params: CreateFileRecordParams): Promise { const { diff --git a/lib/supabase/song_artists/insertSongArtists.ts b/lib/supabase/song_artists/insertSongArtists.ts index 69878d6d..b81879e3 100644 --- a/lib/supabase/song_artists/insertSongArtists.ts +++ b/lib/supabase/song_artists/insertSongArtists.ts @@ -5,8 +5,6 @@ export type SongArtistInsert = TablesInsert<"song_artists">; /** * Inserts song-artist relationships, skipping duplicates. - * - * @param songArtists */ export async function insertSongArtists(songArtists: SongArtistInsert[]): Promise { const records = songArtists.filter( diff --git a/lib/supabase/storage/uploadFileByKey.ts b/lib/supabase/storage/uploadFileByKey.ts index ae149173..ba146fa3 100644 --- a/lib/supabase/storage/uploadFileByKey.ts +++ b/lib/supabase/storage/uploadFileByKey.ts @@ -3,12 +3,6 @@ import { SUPABASE_STORAGE_BUCKET } from "@/lib/const"; /** * Upload file to Supabase storage by key - * - * @param key - * @param file - * @param options - * @param options.contentType - * @param options.upsert */ export async function uploadFileByKey( key: string, diff --git a/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts b/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts index c6082f98..60d38a96 100644 --- a/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts +++ b/lib/tasks/__tests__/enrichTaskWithTriggerInfo.test.ts @@ -1,9 +1,6 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { enrichTaskWithTriggerInfo } from "../enrichTaskWithTriggerInfo"; -import { fetchTriggerRuns } from "@/lib/trigger/fetchTriggerRuns"; -import { retrieveTaskRun } from "@/lib/trigger/retrieveTaskRun"; - vi.mock("@/lib/trigger/fetchTriggerRuns", () => ({ fetchTriggerRuns: vi.fn(), })); @@ -12,6 +9,9 @@ vi.mock("@/lib/trigger/retrieveTaskRun", () => ({ retrieveTaskRun: vi.fn(), })); +import { fetchTriggerRuns } from "@/lib/trigger/fetchTriggerRuns"; +import { retrieveTaskRun } from "@/lib/trigger/retrieveTaskRun"; + const mockTask = { id: "task-123", title: "Test Task", diff --git a/lib/tasks/__tests__/getTaskRunHandler.test.ts b/lib/tasks/__tests__/getTaskRunHandler.test.ts index 3ab107f8..9f17fffc 100644 --- a/lib/tasks/__tests__/getTaskRunHandler.test.ts +++ b/lib/tasks/__tests__/getTaskRunHandler.test.ts @@ -23,9 +23,6 @@ vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => ({ "Access-Control-Allow-Origin": "*" })), })); -/** - * - */ function createMockRequest(): NextRequest { return { url: "http://localhost:3000/api/tasks/runs", diff --git a/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts b/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts index 77d410da..f7126175 100644 --- a/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts +++ b/lib/tasks/__tests__/validateGetTaskRunQuery.test.ts @@ -24,8 +24,6 @@ vi.mock("@/lib/admins/checkIsAdmin", () => ({ /** * Creates a mock NextRequest with the given URL. - * - * @param url */ function createMockRequest(url: string): NextRequest { return { diff --git a/lib/tasks/__tests__/validateGetTasksQuery.test.ts b/lib/tasks/__tests__/validateGetTasksQuery.test.ts index 11226d30..b9d0dda7 100644 --- a/lib/tasks/__tests__/validateGetTasksQuery.test.ts +++ b/lib/tasks/__tests__/validateGetTasksQuery.test.ts @@ -22,10 +22,6 @@ vi.mock("@/lib/admins/checkIsAdmin", () => ({ checkIsAdmin: vi.fn(), })); -/** - * - * @param url - */ function createMockRequest(url: string): NextRequest { return { url, diff --git a/lib/transcribe/processAudioTranscription.ts b/lib/transcribe/processAudioTranscription.ts index 0e05905a..351eee34 100644 --- a/lib/transcribe/processAudioTranscription.ts +++ b/lib/transcribe/processAudioTranscription.ts @@ -7,8 +7,6 @@ import { ProcessTranscriptionParams, ProcessTranscriptionResult } from "./types" /** * Fetches audio from URL, transcribes it with OpenAI Whisper, and saves both * the original audio and transcript markdown to the customer's files. - * - * @param params */ export async function processAudioTranscription( params: ProcessTranscriptionParams, @@ -66,10 +64,6 @@ export async function processAudioTranscription( }; } -/** - * - * @param contentType - */ function getExtensionFromContentType(contentType: string): string { if (contentType.includes("wav")) return "wav"; if (contentType.includes("m4a") || contentType.includes("mp4")) return "m4a"; diff --git a/lib/transcribe/saveAudioToFiles.ts b/lib/transcribe/saveAudioToFiles.ts index 2124e512..12bda1ef 100644 --- a/lib/transcribe/saveAudioToFiles.ts +++ b/lib/transcribe/saveAudioToFiles.ts @@ -2,10 +2,6 @@ import { uploadFileByKey } from "@/lib/supabase/storage/uploadFileByKey"; import { createFileRecord } from "@/lib/supabase/files/createFileRecord"; import { SaveAudioParams, FileRecord } from "./types"; -/** - * - * @param params - */ export async function saveAudioToFiles(params: SaveAudioParams): Promise { const { audioBlob, diff --git a/lib/transcribe/saveTranscriptToFiles.ts b/lib/transcribe/saveTranscriptToFiles.ts index fa7518c5..627feb6d 100644 --- a/lib/transcribe/saveTranscriptToFiles.ts +++ b/lib/transcribe/saveTranscriptToFiles.ts @@ -2,10 +2,6 @@ import { uploadFileByKey } from "@/lib/supabase/storage/uploadFileByKey"; import { createFileRecord } from "@/lib/supabase/files/createFileRecord"; import { SaveTranscriptParams, FileRecord } from "./types"; -/** - * - * @param params - */ export async function saveTranscriptToFiles(params: SaveTranscriptParams): Promise { const { markdown, ownerAccountId, artistAccountId, title = "Transcription" } = params; diff --git a/lib/transcribe/types.ts b/lib/transcribe/types.ts index 916e699c..91c0ac10 100644 --- a/lib/transcribe/types.ts +++ b/lib/transcribe/types.ts @@ -56,8 +56,6 @@ export interface ProcessTranscriptionResult { /** * Formats transcription errors into user-friendly messages. * Centralizes error message logic to avoid duplication. - * - * @param error */ export function formatTranscriptionError(error: unknown): { message: string; status: number } { const rawMessage = error instanceof Error ? error.message : "Transcription failed"; From fa91373bca0458f148d16454cd64c55309341b07 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Wed, 8 Apr 2026 11:06:33 -0500 Subject: [PATCH 5/6] chore: fix formatting in extractMessageAttachments test Co-Authored-By: Claude Opus 4.6 (1M context) --- .../content/__tests__/extractMessageAttachments.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/agents/content/__tests__/extractMessageAttachments.test.ts b/lib/agents/content/__tests__/extractMessageAttachments.test.ts index 61f4ba89..4dee2308 100644 --- a/lib/agents/content/__tests__/extractMessageAttachments.test.ts +++ b/lib/agents/content/__tests__/extractMessageAttachments.test.ts @@ -69,7 +69,9 @@ describe("extractMessageAttachments", () => { const result = await extractMessageAttachments(message as never); - expect(result.imageUrls).toContain("https://blob.vercel-storage.com/content-attachments/face.png"); + expect(result.imageUrls).toContain( + "https://blob.vercel-storage.com/content-attachments/face.png", + ); expect(result.songUrl).toBeNull(); }); From c2f38a2af8a1813b790a54093b15a299927c544a Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Wed, 8 Apr 2026 11:12:06 -0500 Subject: [PATCH 6/6] refactor: extract isSupportedContentTemplate to own file (SRP) Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/content/__tests__/contentTemplates.test.ts | 3 ++- lib/content/contentTemplates.ts | 8 -------- lib/content/isSupportedContentTemplate.ts | 11 +++++++++++ lib/content/validateCreateContentBody.ts | 6 ++---- 4 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 lib/content/isSupportedContentTemplate.ts diff --git a/lib/content/__tests__/contentTemplates.test.ts b/lib/content/__tests__/contentTemplates.test.ts index 1b1dc2de..c735a0a2 100644 --- a/lib/content/__tests__/contentTemplates.test.ts +++ b/lib/content/__tests__/contentTemplates.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; -import { CONTENT_TEMPLATES, isSupportedContentTemplate } from "@/lib/content/contentTemplates"; +import { CONTENT_TEMPLATES } from "@/lib/content/contentTemplates"; +import { isSupportedContentTemplate } from "@/lib/content/isSupportedContentTemplate"; describe("contentTemplates", () => { it("includes artist-release-editorial template", () => { diff --git a/lib/content/contentTemplates.ts b/lib/content/contentTemplates.ts index 97997ea3..e7ecac02 100644 --- a/lib/content/contentTemplates.ts +++ b/lib/content/contentTemplates.ts @@ -34,11 +34,3 @@ export const CONTENT_TEMPLATES: ContentTemplate[] = [ /** Derived from the first entry in CONTENT_TEMPLATES to avoid string duplication. */ export const DEFAULT_CONTENT_TEMPLATE = CONTENT_TEMPLATES[0].name; - -/** - * - * @param template - */ -export function isSupportedContentTemplate(template: string): boolean { - return CONTENT_TEMPLATES.some(item => item.name === template); -} diff --git a/lib/content/isSupportedContentTemplate.ts b/lib/content/isSupportedContentTemplate.ts new file mode 100644 index 00000000..68d34f8c --- /dev/null +++ b/lib/content/isSupportedContentTemplate.ts @@ -0,0 +1,11 @@ +import { CONTENT_TEMPLATES } from "./contentTemplates"; + +/** + * Checks if a template name is in the supported templates list. + * + * @param template - The template name to validate + * @returns Whether the template is supported + */ +export function isSupportedContentTemplate(template: string): boolean { + return CONTENT_TEMPLATES.some(item => item.name === template); +} diff --git a/lib/content/validateCreateContentBody.ts b/lib/content/validateCreateContentBody.ts index 80049ce1..f6dccad0 100644 --- a/lib/content/validateCreateContentBody.ts +++ b/lib/content/validateCreateContentBody.ts @@ -4,10 +4,8 @@ import { z } from "zod"; import { getCorsHeaders } from "@/lib/networking/getCorsHeaders"; import { safeParseJson } from "@/lib/networking/safeParseJson"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; -import { - DEFAULT_CONTENT_TEMPLATE, - isSupportedContentTemplate, -} from "@/lib/content/contentTemplates"; +import { DEFAULT_CONTENT_TEMPLATE } from "@/lib/content/contentTemplates"; +import { isSupportedContentTemplate } from "@/lib/content/isSupportedContentTemplate"; import { resolveArtistSlug } from "@/lib/content/resolveArtistSlug"; import { songsSchema } from "@/lib/content/songsSchema";