From d3e32b6a2540a5164ee250de91f0d05c3fa8b329 Mon Sep 17 00:00:00 2001 From: Recoup Agent Date: Fri, 13 Mar 2026 13:55:55 +0000 Subject: [PATCH] agent: @U0AJM7X8FBR API - slack client we want to expand our current Slack inte --- src/artists/getBatchArtistSocials.ts | 13 ++-- src/artists/isScrapableSocial.ts | 4 +- src/chats/getTaskRoomId.ts | 4 +- src/consts.ts | 2 +- .../__tests__/createOrgGithubRepo.test.ts | 11 +-- src/github/createGithubRepo.ts | 29 ++++---- src/github/createOrgGithubRepo.ts | 31 ++++---- src/github/getExistingGithubRepo.ts | 21 ++---- src/polling/pollScraperResults.ts | 12 ++- .../__tests__/executePulseInSandbox.test.ts | 6 +- src/pulse/executePulseInSandbox.ts | 3 + src/recoup/__tests__/getAccountOrgs.test.ts | 4 +- src/recoup/createAccountSandbox.ts | 2 +- src/recoup/createChat.ts | 4 +- src/recoup/fetchActivePulses.ts | 2 +- src/recoup/fetchTask.ts | 8 +- src/recoup/generateChat.ts | 2 +- src/recoup/getAccount.ts | 4 +- src/recoup/getAccountOrgs.ts | 8 +- src/recoup/getAccountSandboxes.ts | 6 +- src/recoup/getArtistSocials.ts | 12 +-- src/recoup/getProArtists.ts | 3 + src/recoup/getScraperResults.ts | 7 +- src/recoup/scrapeSocial.ts | 6 +- src/recoup/updateAccountSnapshot.ts | 2 +- .../__tests__/addOrgSubmodules.test.ts | 28 +++---- .../__tests__/cloneMonorepoViaAgent.test.ts | 1 - .../__tests__/configureGitAuth.test.ts | 8 +- .../__tests__/copyOpenClawToRepo.test.ts | 17 ++--- .../__tests__/ensureOrgRepos.test.ts | 36 ++++----- .../__tests__/getGitHubAuthPrefix.test.ts | 4 +- .../__tests__/getOrCreateSandbox.test.ts | 16 +--- .../__tests__/getSandboxHomeDir.test.ts | 4 + .../notifyCodingAgentCallback.test.ts | 4 +- src/sandboxes/__tests__/pushOrgRepos.test.ts | 14 ++-- .../__tests__/runOpenClawAgent.test.ts | 4 +- src/sandboxes/__tests__/setupOpenClaw.test.ts | 74 ++++++++----------- .../__tests__/snapshotAndPersist.test.ts | 3 + .../__tests__/stripGitmodulesTokens.test.ts | 9 ++- src/sandboxes/cloneMonorepoViaAgent.ts | 4 +- src/sandboxes/configureGitAuth.ts | 9 +-- src/sandboxes/ensureGithubRepo.ts | 18 +---- src/sandboxes/ensureOrgRepos.ts | 14 +--- src/sandboxes/ensureSetupSandbox.ts | 5 +- src/sandboxes/getOrCreateSandbox.ts | 4 +- src/sandboxes/getSandboxEnv.ts | 6 +- src/sandboxes/getVercelSandboxCredentials.ts | 2 +- src/sandboxes/git/addOrgSubmodules.ts | 2 +- src/sandboxes/git/pushOrgRepos.ts | 6 +- src/sandboxes/installSkill.ts | 5 +- src/sandboxes/logStep.ts | 6 +- src/sandboxes/notifyCodingAgentCallback.ts | 5 +- src/sandboxes/onboardOpenClaw.ts | 2 +- src/sandboxes/parsePRUrls.ts | 6 +- src/sandboxes/pushSandboxToGithub.ts | 24 ++---- src/sandboxes/runGitCommand.ts | 5 +- src/sandboxes/runOpenClawAgent.ts | 2 +- src/sandboxes/runSetupArtistSkill.ts | 2 +- src/sandboxes/runSetupSandboxSkill.ts | 2 +- src/sandboxes/setupOpenClaw.ts | 5 +- src/sandboxes/snapshotAndPersist.ts | 6 +- src/sandboxes/writeReadme.ts | 2 +- src/schemas/sandboxSchema.ts | 4 +- src/socials/filterScrapableSocials.ts | 8 +- src/socials/scrapeAndPollSocials.ts | 24 +++--- src/tasks/__tests__/codingAgentTask.test.ts | 11 ++- src/tasks/__tests__/sendPulsesTask.test.ts | 5 +- src/tasks/__tests__/setupSandboxTask.test.ts | 18 ++--- src/tasks/__tests__/updatePRTask.test.ts | 4 +- src/tasks/codingAgentTask.ts | 7 +- src/tasks/customerPromptTask.ts | 4 +- src/tasks/proArtistSocialProfilesScrape.ts | 14 ++-- src/tasks/runSandboxCommandTask.ts | 11 +-- src/tasks/sendPulsesTask.ts | 4 +- src/tasks/setupSandboxTask.ts | 8 +- src/tasks/updatePRTask.ts | 2 +- 76 files changed, 287 insertions(+), 407 deletions(-) diff --git a/src/artists/getBatchArtistSocials.ts b/src/artists/getBatchArtistSocials.ts index e23c313..a4fed9b 100644 --- a/src/artists/getBatchArtistSocials.ts +++ b/src/artists/getBatchArtistSocials.ts @@ -4,23 +4,20 @@ import { getArtistSocials } from "../recoup/getArtistSocials"; /** * Fetches socials for all artists in parallel. * Returns a Map of artistId -> socials array. + * + * @param artistIds */ export async function getBatchArtistSocials( - artistIds: string[] + artistIds: string[], ): Promise>>> { logger.log("Fetching socials for all artists", { totalArtists: artistIds.length, }); - const socialsResponses = await Promise.all( - artistIds.map((artistId) => getArtistSocials(artistId)) - ); + const socialsResponses = await Promise.all(artistIds.map(artistId => getArtistSocials(artistId))); // Store socials in map - const artistSocialsMap = new Map< - string, - Awaited> - >(); + const artistSocialsMap = new Map>>(); for (let i = 0; i < artistIds.length; i++) { artistSocialsMap.set(artistIds[i], socialsResponses[i]); diff --git a/src/artists/isScrapableSocial.ts b/src/artists/isScrapableSocial.ts index 119f5bd..248358d 100644 --- a/src/artists/isScrapableSocial.ts +++ b/src/artists/isScrapableSocial.ts @@ -12,6 +12,8 @@ import type { ArtistSocialProfile } from "../recoup/getArtistSocials"; * * Non-scrapable platforms: * - open.spotify.com + * + * @param social */ export function isScrapableSocial(social: ArtistSocialProfile): boolean { const profileUrl = social.profile_url.toLowerCase(); @@ -39,5 +41,5 @@ export function isScrapableSocial(social: ArtistSocialProfile): boolean { "youtube.com", ]; - return scrapableDomains.some((domain) => profileUrl.includes(domain)); + return scrapableDomains.some(domain => profileUrl.includes(domain)); } diff --git a/src/chats/getTaskRoomId.ts b/src/chats/getTaskRoomId.ts index ad92858..7795038 100644 --- a/src/chats/getTaskRoomId.ts +++ b/src/chats/getTaskRoomId.ts @@ -14,9 +14,7 @@ type GetTaskRoomIdParams = { * @param params - Parameters containing optional roomId and artistId * @returns The room ID, or undefined if creation fails */ -export async function getTaskRoomId( - params: GetTaskRoomIdParams -): Promise { +export async function getTaskRoomId(params: GetTaskRoomIdParams): Promise { if (params.roomId) { logger.log("Using existing roomId", { roomId: params.roomId }); return params.roomId; diff --git a/src/consts.ts b/src/consts.ts index 2af388d..6962140 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -1,2 +1,2 @@ export const NEW_API_BASE_URL = "https://recoup-api.vercel.app"; -export const RECOUP_API_KEY = process.env.RECOUP_API_KEY; \ No newline at end of file +export const RECOUP_API_KEY = process.env.RECOUP_API_KEY; diff --git a/src/github/__tests__/createOrgGithubRepo.test.ts b/src/github/__tests__/createOrgGithubRepo.test.ts index b03395b..03f82ef 100644 --- a/src/github/__tests__/createOrgGithubRepo.test.ts +++ b/src/github/__tests__/createOrgGithubRepo.test.ts @@ -26,9 +26,7 @@ describe("createOrgGithubRepo", () => { const result = await createOrgGithubRepo("Test Org", "uuid-123"); - expect(result).toBe( - "https://github.com/Recoupable-Com/org-test-org-uuid-123" - ); + expect(result).toBe("https://github.com/Recoupable-Com/org-test-org-uuid-123"); expect(mockFetch).toHaveBeenCalledOnce(); // Verify the request body has the right repo name and auto_init @@ -57,9 +55,7 @@ describe("createOrgGithubRepo", () => { const result = await createOrgGithubRepo("My Org", "uuid-456"); - expect(result).toBe( - "https://github.com/Recoupable-Com/org-my-org-uuid-456" - ); + expect(result).toBe("https://github.com/Recoupable-Com/org-my-org-uuid-456"); expect(mockFetch).toHaveBeenCalledTimes(2); }); @@ -104,8 +100,7 @@ describe("createOrgGithubRepo", () => { mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ - html_url: - "https://github.com/Recoupable-Com/org-my-cool-org-uuid-111", + html_url: "https://github.com/Recoupable-Com/org-my-cool-org-uuid-111", }), }); diff --git a/src/github/createGithubRepo.ts b/src/github/createGithubRepo.ts index 1c28d0e..828c9ca 100644 --- a/src/github/createGithubRepo.ts +++ b/src/github/createGithubRepo.ts @@ -13,7 +13,7 @@ const GITHUB_ORG = "recoupable"; */ export async function createGithubRepo( accountName: string, - accountId: string + accountId: string, ): Promise { const token = process.env.GITHUB_TOKEN; @@ -32,21 +32,18 @@ export async function createGithubRepo( }); try { - const response = await fetch( - `https://api.github.com/orgs/${GITHUB_ORG}/repos`, - { - method: "POST", - headers: { - Accept: "application/vnd.github+json", - Authorization: `Bearer ${token}`, - "X-GitHub-Api-Version": "2022-11-28", - }, - body: JSON.stringify({ - name: repoName, - private: true, - }), - } - ); + const response = await fetch(`https://api.github.com/orgs/${GITHUB_ORG}/repos`, { + method: "POST", + headers: { + Accept: "application/vnd.github+json", + Authorization: `Bearer ${token}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + body: JSON.stringify({ + name: repoName, + private: true, + }), + }); if (!response.ok) { // 422 means repo already exists — fetch existing URL diff --git a/src/github/createOrgGithubRepo.ts b/src/github/createOrgGithubRepo.ts index aa84640..1e43166 100644 --- a/src/github/createOrgGithubRepo.ts +++ b/src/github/createOrgGithubRepo.ts @@ -16,7 +16,7 @@ const GITHUB_ORG = "recoupable"; */ export async function createOrgGithubRepo( orgName: string, - orgId: string + orgId: string, ): Promise { const token = process.env.GITHUB_TOKEN; @@ -35,22 +35,19 @@ export async function createOrgGithubRepo( }); try { - const response = await fetch( - `https://api.github.com/orgs/${GITHUB_ORG}/repos`, - { - method: "POST", - headers: { - Accept: "application/vnd.github+json", - Authorization: `Bearer ${token}`, - "X-GitHub-Api-Version": "2022-11-28", - }, - body: JSON.stringify({ - name: repoName, - private: true, - auto_init: true, - }), - } - ); + const response = await fetch(`https://api.github.com/orgs/${GITHUB_ORG}/repos`, { + method: "POST", + headers: { + Accept: "application/vnd.github+json", + Authorization: `Bearer ${token}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + body: JSON.stringify({ + name: repoName, + private: true, + auto_init: true, + }), + }); if (!response.ok) { // 422 means repo already exists — fetch existing URL diff --git a/src/github/getExistingGithubRepo.ts b/src/github/getExistingGithubRepo.ts index 2c9d060..1b26a25 100644 --- a/src/github/getExistingGithubRepo.ts +++ b/src/github/getExistingGithubRepo.ts @@ -8,9 +8,7 @@ const GITHUB_ORG = "recoupable"; * @param repoName - The full repository name (e.g. "account-name-uuid") * @returns The repository HTML URL, or undefined if not found or on error */ -export async function getExistingGithubRepo( - repoName: string -): Promise { +export async function getExistingGithubRepo(repoName: string): Promise { const token = process.env.GITHUB_TOKEN; if (!token) { @@ -24,16 +22,13 @@ export async function getExistingGithubRepo( }); try { - const response = await fetch( - `https://api.github.com/repos/${GITHUB_ORG}/${repoName}`, - { - headers: { - Accept: "application/vnd.github+json", - Authorization: `Bearer ${token}`, - "X-GitHub-Api-Version": "2022-11-28", - }, - } - ); + const response = await fetch(`https://api.github.com/repos/${GITHUB_ORG}/${repoName}`, { + headers: { + Accept: "application/vnd.github+json", + Authorization: `Bearer ${token}`, + "X-GitHub-Api-Version": "2022-11-28", + }, + }); if (!response.ok) { logger.error("Failed to fetch existing GitHub repo", { diff --git a/src/polling/pollScraperResults.ts b/src/polling/pollScraperResults.ts index ed8af96..2a7f729 100644 --- a/src/polling/pollScraperResults.ts +++ b/src/polling/pollScraperResults.ts @@ -15,18 +15,16 @@ export type PollResult = ScrapeRun & { /** * Polls each scraper run in parallel until all are completed (SUCCEEDED or FAILED). * Returns an array of results for each run. + * + * @param runs */ -export async function pollScraperResults( - runs: ScrapeRun[] -): Promise { +export async function pollScraperResults(runs: ScrapeRun[]): Promise { const results: PollResult[] = []; - const pendingRuns = new Map( - runs.map((run) => [run.runId, run]) - ); + const pendingRuns = new Map(runs.map(run => [run.runId, run])); while (pendingRuns.size > 0) { // Poll all pending runs in parallel - const pollPromises = Array.from(pendingRuns.values()).map(async (run) => { + const pollPromises = Array.from(pendingRuns.values()).map(async run => { const result = await getScraperResults(run.runId); if (!result) { diff --git a/src/pulse/__tests__/executePulseInSandbox.test.ts b/src/pulse/__tests__/executePulseInSandbox.test.ts index 13bc95a..254c4c8 100644 --- a/src/pulse/__tests__/executePulseInSandbox.test.ts +++ b/src/pulse/__tests__/executePulseInSandbox.test.ts @@ -114,9 +114,9 @@ describe("executePulseInSandbox", () => { })); const mod = await import("../executePulseInSandbox"); - await expect( - mod.executePulseInSandbox({ accountId, prompt }) - ).rejects.toThrow("RECOUP_API_KEY not configured"); + await expect(mod.executePulseInSandbox({ accountId, prompt })).rejects.toThrow( + "RECOUP_API_KEY not configured", + ); process.env.RECOUP_API_KEY = original; }); diff --git a/src/pulse/executePulseInSandbox.ts b/src/pulse/executePulseInSandbox.ts index aedb49d..87a863b 100644 --- a/src/pulse/executePulseInSandbox.ts +++ b/src/pulse/executePulseInSandbox.ts @@ -21,6 +21,9 @@ const executePulseResponseSchema = z.object({ * * @param params.accountId - The account ID to execute the pulse for * @param params.prompt - The pulse prompt to execute + * @param root0 + * @param root0.accountId + * @param root0.prompt * @returns The sandbox ID and run ID on success, undefined on error */ export async function executePulseInSandbox({ diff --git a/src/recoup/__tests__/getAccountOrgs.test.ts b/src/recoup/__tests__/getAccountOrgs.test.ts index 5a3c163..8ebcedc 100644 --- a/src/recoup/__tests__/getAccountOrgs.test.ts +++ b/src/recoup/__tests__/getAccountOrgs.test.ts @@ -40,9 +40,7 @@ describe("getAccountOrgs", () => { { organizationId: "org-456", organizationName: "Another Org" }, ]); expect(mockFetch).toHaveBeenCalledOnce(); - expect(mockFetch.mock.calls[0][0]).toContain( - "/api/organizations?account_id=account-1" - ); + expect(mockFetch.mock.calls[0][0]).toContain("/api/organizations?account_id=account-1"); }); it("returns empty array when account has no orgs", async () => { diff --git a/src/recoup/createAccountSandbox.ts b/src/recoup/createAccountSandbox.ts index b8bab9f..aa0105a 100644 --- a/src/recoup/createAccountSandbox.ts +++ b/src/recoup/createAccountSandbox.ts @@ -19,7 +19,7 @@ const createSandboxResponseSchema = z.object({ * @returns The created sandbox ID, or undefined on error */ export async function createAccountSandbox( - accountId: string + accountId: string, ): Promise<{ sandboxId: string } | undefined> { const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent(accountId)}`; diff --git a/src/recoup/createChat.ts b/src/recoup/createChat.ts index 53e2d2e..5d95cd3 100644 --- a/src/recoup/createChat.ts +++ b/src/recoup/createChat.ts @@ -23,9 +23,7 @@ type CreateChatResponse = { * @param params - Chat creation parameters * @returns Promise that resolves to the created chat, or undefined on error */ -export async function createChat( - params?: CreateChatParams -): Promise { +export async function createChat(params?: CreateChatParams): Promise { if (!RECOUP_API_KEY) { logger.error("Missing RECOUP_API_KEY environment variable"); return undefined; diff --git a/src/recoup/fetchActivePulses.ts b/src/recoup/fetchActivePulses.ts index f468ca8..0a5c088 100644 --- a/src/recoup/fetchActivePulses.ts +++ b/src/recoup/fetchActivePulses.ts @@ -60,7 +60,7 @@ export async function fetchActivePulses(): Promise { logger.log("Fetched active pulses", { count: pulses.length, - pulses: pulses.map((p) => ({ + pulses: pulses.map(p => ({ id: p.id, account_id: p.account_id, active: p.active, diff --git a/src/recoup/fetchTask.ts b/src/recoup/fetchTask.ts index 4799da5..8daab5e 100644 --- a/src/recoup/fetchTask.ts +++ b/src/recoup/fetchTask.ts @@ -16,7 +16,7 @@ const taskResponseSchema = z.object({ artist_account_id: z.string(), enabled: z.boolean().nullable(), model: z.string().nullish(), - }) + }), ), }); @@ -27,10 +27,10 @@ const taskResponseSchema = z.object({ * - Task not found * - Task is disabled * - API error occurs + * + * @param externalId */ -export async function fetchTask( - externalId?: string -): Promise { +export async function fetchTask(externalId?: string): Promise { if (!externalId) { logger.warn("No externalId provided, skipping task fetch"); return undefined; diff --git a/src/recoup/generateChat.ts b/src/recoup/generateChat.ts index 630bfb1..d9dc630 100644 --- a/src/recoup/generateChat.ts +++ b/src/recoup/generateChat.ts @@ -25,7 +25,7 @@ type ChatGenerateResponse = { * @returns Promise that resolves to the parsed response, or undefined on error */ export async function generateChat( - params: ChatGenerateParams + params: ChatGenerateParams, ): Promise { if (!RECOUP_API_KEY) { logger.error("Missing RECOUP_API_KEY environment variable"); diff --git a/src/recoup/getAccount.ts b/src/recoup/getAccount.ts index ba68bce..784fb5f 100644 --- a/src/recoup/getAccount.ts +++ b/src/recoup/getAccount.ts @@ -21,9 +21,7 @@ export interface AccountInfo { * @param accountId - The account ID to look up * @returns The account id and name, or undefined on error */ -export async function getAccount( - accountId: string -): Promise { +export async function getAccount(accountId: string): Promise { const url = `${NEW_API_BASE_URL}/api/accounts/${encodeURIComponent(accountId)}`; logger.log("Fetching account info", { accountId, url }); diff --git a/src/recoup/getAccountOrgs.ts b/src/recoup/getAccountOrgs.ts index 8937ec6..bf60a7d 100644 --- a/src/recoup/getAccountOrgs.ts +++ b/src/recoup/getAccountOrgs.ts @@ -23,9 +23,7 @@ export interface OrgInfo { * @param accountId - The account ID to look up orgs for * @returns Array of org id/name pairs, or undefined on error */ -export async function getAccountOrgs( - accountId: string -): Promise { +export async function getAccountOrgs(accountId: string): Promise { const url = `${NEW_API_BASE_URL}/api/organizations?account_id=${encodeURIComponent(accountId)}`; logger.log("Fetching account organizations", { accountId, url }); @@ -59,8 +57,8 @@ export async function getAccountOrgs( } const orgs = validation.data.organizations - .filter((org) => org.organization_id && org.organization_name) - .map((org) => ({ + .filter(org => org.organization_id && org.organization_name) + .map(org => ({ organizationId: org.organization_id, organizationName: org.organization_name!, })); diff --git a/src/recoup/getAccountSandboxes.ts b/src/recoup/getAccountSandboxes.ts index 5b01af2..425aa73 100644 --- a/src/recoup/getAccountSandboxes.ts +++ b/src/recoup/getAccountSandboxes.ts @@ -20,11 +20,9 @@ export interface AccountSandboxesInfo { * @returns The snapshot ID and github repo URL, or undefined on error */ export async function getAccountSandboxes( - accountId: string + accountId: string, ): Promise { - const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent( - accountId - )}`; + const url = `${NEW_API_BASE_URL}/api/sandboxes?account_id=${encodeURIComponent(accountId)}`; logger.log("Fetching account sandboxes", { accountId, url }); diff --git a/src/recoup/getArtistSocials.ts b/src/recoup/getArtistSocials.ts index f055c17..1851841 100644 --- a/src/recoup/getArtistSocials.ts +++ b/src/recoup/getArtistSocials.ts @@ -15,7 +15,7 @@ const artistSocialsResponseSchema = z.object({ following_count: z.number().nullable(), region: z.string().nullable(), updated_at: z.string(), - }) + }), ), pagination: z .object({ @@ -27,14 +27,16 @@ const artistSocialsResponseSchema = z.object({ .optional(), }); -export type ArtistSocialProfile = z.infer< - typeof artistSocialsResponseSchema ->["socials"][number]; +export type ArtistSocialProfile = z.infer["socials"][number]; const ARTIST_SOCIALS_API_URL = "https://api.recoupable.com/api/artist/socials"; +/** + * + * @param artistAccountId + */ export async function getArtistSocials( - artistAccountId: string + artistAccountId: string, ): Promise { if (!artistAccountId) { logger.error("getArtistSocials called without artistAccountId"); diff --git a/src/recoup/getProArtists.ts b/src/recoup/getProArtists.ts index 13a361d..51d13fa 100644 --- a/src/recoup/getProArtists.ts +++ b/src/recoup/getProArtists.ts @@ -8,6 +8,9 @@ const proArtistsResponseSchema = z.object({ const PRO_ARTISTS_API_URL = "https://api.recoupable.com/api/artists/pro"; +/** + * + */ export async function getProArtists(): Promise { try { const response = await fetch(PRO_ARTISTS_API_URL, { diff --git a/src/recoup/getScraperResults.ts b/src/recoup/getScraperResults.ts index 7f8eba6..f9c875e 100644 --- a/src/recoup/getScraperResults.ts +++ b/src/recoup/getScraperResults.ts @@ -21,10 +21,10 @@ const APIFY_SCRAPER_API_URL = "https://api.recoupable.com/api/apify/scraper"; /** * Checks the status and retrieves results from an Apify scraper run. * Returns the response with status and data (if completed). + * + * @param runId */ -export async function getScraperResults( - runId: string -): Promise { +export async function getScraperResults(runId: string): Promise { if (!runId) { logger.error("getScraperResults called without runId"); return undefined; @@ -80,4 +80,3 @@ export async function getScraperResults( return undefined; } } - diff --git a/src/recoup/scrapeSocial.ts b/src/recoup/scrapeSocial.ts index e1670af..7d85e42 100644 --- a/src/recoup/scrapeSocial.ts +++ b/src/recoup/scrapeSocial.ts @@ -14,10 +14,10 @@ const SOCIAL_SCRAPE_API_URL = "https://api.recoupable.com/api/social/scrape"; /** * Triggers a social profile scraping job for a given social_id. * Returns Apify run metadata that can be used to poll for status and retrieve results. + * + * @param socialId */ -export async function scrapeSocial( - socialId: string -): Promise { +export async function scrapeSocial(socialId: string): Promise { if (!socialId) { logger.error("scrapeSocial called without socialId"); return undefined; diff --git a/src/recoup/updateAccountSnapshot.ts b/src/recoup/updateAccountSnapshot.ts index 8be278a..2dd1b54 100644 --- a/src/recoup/updateAccountSnapshot.ts +++ b/src/recoup/updateAccountSnapshot.ts @@ -12,7 +12,7 @@ import { NEW_API_BASE_URL, RECOUP_API_KEY } from "../consts"; export async function updateAccountSnapshot( accountId: string, snapshotId?: string, - githubRepo?: string + githubRepo?: string, ): Promise<{ success: boolean; snapshotId: string } | undefined> { const url = `${NEW_API_BASE_URL}/api/sandboxes`; diff --git a/src/sandboxes/__tests__/addOrgSubmodules.test.ts b/src/sandboxes/__tests__/addOrgSubmodules.test.ts index 969e768..d63c32f 100644 --- a/src/sandboxes/__tests__/addOrgSubmodules.test.ts +++ b/src/sandboxes/__tests__/addOrgSubmodules.test.ts @@ -10,6 +10,9 @@ vi.mock("../getSandboxHomeDir", () => ({ const { addOrgSubmodules } = await import("../git/addOrgSubmodules"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0, @@ -51,9 +54,7 @@ describe("addOrgSubmodules", () => { await addOrgSubmodules(sandbox); const submoduleCalls = sandbox.runCommand.mock.calls.filter( - (call: any[]) => - call[0]?.cmd === "git" && - call[0]?.args?.[0] === "submodule" + (call: any[]) => call[0]?.cmd === "git" && call[0]?.args?.[0] === "submodule", ); expect(submoduleCalls).toHaveLength(0); }); @@ -86,10 +87,7 @@ describe("addOrgSubmodules", () => { }; } } - if ( - opts.cmd === "sh" && - opts.args?.[1]?.includes("git config --file .gitmodules") - ) { + if (opts.cmd === "sh" && opts.args?.[1]?.includes("git config --file .gitmodules")) { return { exitCode: 1, stdout: async () => "", stderr: async () => "" }; } return { exitCode: 0, stdout: async () => "", stderr: async () => "" }; @@ -101,7 +99,7 @@ describe("addOrgSubmodules", () => { (call: any[]) => call[0]?.cmd === "git" && call[0]?.args?.[0] === "submodule" && - call[0]?.args?.[1] === "add" + call[0]?.args?.[1] === "add", ); expect(submoduleCalls).toHaveLength(2); @@ -128,10 +126,7 @@ describe("addOrgSubmodules", () => { stderr: async () => "", }; } - if ( - opts.cmd === "sh" && - opts.args?.[1]?.includes("git config --file .gitmodules") - ) { + if (opts.cmd === "sh" && opts.args?.[1]?.includes("git config --file .gitmodules")) { return { exitCode: 0, stdout: async () => "", stderr: async () => "" }; } return { exitCode: 0, stdout: async () => "", stderr: async () => "" }; @@ -143,7 +138,7 @@ describe("addOrgSubmodules", () => { (call: any[]) => call[0]?.cmd === "git" && call[0]?.args?.[0] === "submodule" && - call[0]?.args?.[1] === "add" + call[0]?.args?.[1] === "add", ); expect(submoduleCalls).toHaveLength(0); }); @@ -166,10 +161,7 @@ describe("addOrgSubmodules", () => { stderr: async () => "", }; } - if ( - opts.cmd === "sh" && - opts.args?.[1]?.includes("git config --file .gitmodules") - ) { + if (opts.cmd === "sh" && opts.args?.[1]?.includes("git config --file .gitmodules")) { return { exitCode: 1, stdout: async () => "", stderr: async () => "" }; } return { exitCode: 0, stdout: async () => "", stderr: async () => "" }; @@ -181,7 +173,7 @@ describe("addOrgSubmodules", () => { (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("git rm") && - call[0]?.args?.[1]?.includes("--cached") + call[0]?.args?.[1]?.includes("--cached"), ); expect(cleanupCall).toBeDefined(); }); diff --git a/src/sandboxes/__tests__/cloneMonorepoViaAgent.test.ts b/src/sandboxes/__tests__/cloneMonorepoViaAgent.test.ts index d02d8c0..cdc27a8 100644 --- a/src/sandboxes/__tests__/cloneMonorepoViaAgent.test.ts +++ b/src/sandboxes/__tests__/cloneMonorepoViaAgent.test.ts @@ -51,5 +51,4 @@ describe("cloneMonorepoViaAgent", () => { const message = vi.mocked(runOpenClawAgent).mock.calls[0][1].message; expect(message).not.toContain("git config"); }); - }); diff --git a/src/sandboxes/__tests__/configureGitAuth.test.ts b/src/sandboxes/__tests__/configureGitAuth.test.ts index 33e92a5..ae53a39 100644 --- a/src/sandboxes/__tests__/configureGitAuth.test.ts +++ b/src/sandboxes/__tests__/configureGitAuth.test.ts @@ -6,6 +6,9 @@ vi.mock("@trigger.dev/sdk/v3", () => ({ const { configureGitAuth } = await import("../configureGitAuth"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0 }); return { runCommand } as any; @@ -61,9 +64,8 @@ describe("configureGitAuth", () => { await configureGitAuth(sandbox); - const insteadOfCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.args?.some?.((a: string) => a.includes("insteadOf")) + const insteadOfCall = sandbox.runCommand.mock.calls.find((call: any[]) => + call[0]?.args?.some?.((a: string) => a.includes("insteadOf")), ); expect(insteadOfCall).toBeUndefined(); }); diff --git a/src/sandboxes/__tests__/copyOpenClawToRepo.test.ts b/src/sandboxes/__tests__/copyOpenClawToRepo.test.ts index e49264a..5a76367 100644 --- a/src/sandboxes/__tests__/copyOpenClawToRepo.test.ts +++ b/src/sandboxes/__tests__/copyOpenClawToRepo.test.ts @@ -6,6 +6,9 @@ vi.mock("@trigger.dev/sdk/v3", () => ({ const { copyOpenClawToRepo } = await import("../copyOpenClawToRepo"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0, @@ -29,7 +32,7 @@ describe("copyOpenClawToRepo", () => { (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("cp -r") && - call[0]?.args?.[1]?.includes(".openclaw") + call[0]?.args?.[1]?.includes(".openclaw"), ); expect(copyCall).toBeDefined(); @@ -43,9 +46,7 @@ describe("copyOpenClawToRepo", () => { await copyOpenClawToRepo(sandbox); const copyCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.cmd === "sh" && - call[0]?.args?.[1]?.includes("cp -r") + (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("cp -r"), ); const cmd = copyCall![0].args[1]; expect(cmd).toContain("find /vercel/sandbox/.openclaw -name .git"); @@ -58,9 +59,7 @@ describe("copyOpenClawToRepo", () => { await copyOpenClawToRepo(sandbox); const submoduleCalls = sandbox.runCommand.mock.calls.filter( - (call: any[]) => - call[0]?.cmd === "git" && - call[0]?.args?.[0] === "submodule" + (call: any[]) => call[0]?.cmd === "git" && call[0]?.args?.[0] === "submodule", ); expect(submoduleCalls).toHaveLength(0); }); @@ -71,9 +70,7 @@ describe("copyOpenClawToRepo", () => { await copyOpenClawToRepo(sandbox); const sedCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.cmd === "sh" && - call[0]?.args?.[1]?.includes("x-access-token") + (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("x-access-token"), ); expect(sedCall).toBeUndefined(); }); diff --git a/src/sandboxes/__tests__/ensureOrgRepos.test.ts b/src/sandboxes/__tests__/ensureOrgRepos.test.ts index 63ab5f9..b46e1e1 100644 --- a/src/sandboxes/__tests__/ensureOrgRepos.test.ts +++ b/src/sandboxes/__tests__/ensureOrgRepos.test.ts @@ -12,12 +12,14 @@ vi.mock("../../recoup/getAccountOrgs", () => ({ const mockCreateOrgGithubRepo = vi.fn(); vi.mock("../../github/createOrgGithubRepo", () => ({ - createOrgGithubRepo: (...args: unknown[]) => - mockCreateOrgGithubRepo(...args), + createOrgGithubRepo: (...args: unknown[]) => mockCreateOrgGithubRepo(...args), })); const { ensureOrgRepos } = await import("../ensureOrgRepos"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0, @@ -85,7 +87,7 @@ describe("ensureOrgRepos", () => { ]); mockCreateOrgGithubRepo.mockResolvedValueOnce( - "https://github.com/recoupable/org-test-org-org-1" + "https://github.com/recoupable/org-test-org-org-1", ); const sandbox = createMockSandbox(); @@ -94,15 +96,13 @@ describe("ensureOrgRepos", () => { // Should have called openclaw agent with a message about cloning const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); expect(openclawCall).toBeDefined(); // The openclaw args should include the repo URL const args = openclawCall![0].args; - const message = args.find( - (a: string, i: number) => args[i - 1] === "--message" - ); + const message = args.find((a: string, i: number) => args[i - 1] === "--message"); expect(message).toContain("org-test-org-org-1"); // GITHUB_TOKEN is injected into openclaw.json by setupOpenClaw, @@ -117,7 +117,7 @@ describe("ensureOrgRepos", () => { ]); mockCreateOrgGithubRepo.mockResolvedValueOnce( - "https://github.com/recoupable/org-test-org-org-1" + "https://github.com/recoupable/org-test-org-org-1", ); const sandbox = createMockSandbox(); @@ -125,9 +125,7 @@ describe("ensureOrgRepos", () => { await ensureOrgRepos(sandbox, "account-1"); const submoduleCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.cmd === "git" && - call[0]?.args?.[0] === "submodule" + (call: any[]) => call[0]?.cmd === "git" && call[0]?.args?.[0] === "submodule", ); expect(submoduleCall).toBeUndefined(); }); @@ -140,9 +138,7 @@ describe("ensureOrgRepos", () => { mockCreateOrgGithubRepo .mockResolvedValueOnce(undefined) - .mockResolvedValueOnce( - "https://github.com/recoupable/org-working-org-org-2" - ); + .mockResolvedValueOnce("https://github.com/recoupable/org-working-org-org-2"); const sandbox = createMockSandbox(); @@ -152,7 +148,7 @@ describe("ensureOrgRepos", () => { // Openclaw should still be called with the one that succeeded const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); expect(openclawCall).toBeDefined(); }); @@ -169,7 +165,7 @@ describe("ensureOrgRepos", () => { ]); mockCreateOrgGithubRepo.mockResolvedValueOnce( - "https://github.com/recoupable/org-test-org-org-1" + "https://github.com/recoupable/org-test-org-org-1", ); const sandbox = createMockSandbox(); @@ -177,12 +173,10 @@ describe("ensureOrgRepos", () => { await ensureOrgRepos(sandbox, "account-1"); const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); const args = openclawCall![0].args; - const message = args.find( - (a: string, i: number) => args[i - 1] === "--message" - ); + const message = args.find((a: string, i: number) => args[i - 1] === "--message"); // Message must handle .git as a file (submodule gitlink), not just directory expect(message).toContain(".git file"); @@ -200,7 +194,7 @@ describe("ensureOrgRepos", () => { await ensureOrgRepos(sandbox, "account-1"); const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); expect(openclawCall).toBeUndefined(); }); diff --git a/src/sandboxes/__tests__/getGitHubAuthPrefix.test.ts b/src/sandboxes/__tests__/getGitHubAuthPrefix.test.ts index 16fdbed..8b77c53 100644 --- a/src/sandboxes/__tests__/getGitHubAuthPrefix.test.ts +++ b/src/sandboxes/__tests__/getGitHubAuthPrefix.test.ts @@ -10,9 +10,7 @@ describe("getGitHubAuthPrefix", () => { it("returns the auth URL prefix when GITHUB_TOKEN is set", () => { const result = getGitHubAuthPrefix(); - expect(result).toBe( - "https://x-access-token:ghp_test123@github.com/", - ); + expect(result).toBe("https://x-access-token:ghp_test123@github.com/"); }); it("returns null when GITHUB_TOKEN is missing", () => { diff --git a/src/sandboxes/__tests__/getOrCreateSandbox.test.ts b/src/sandboxes/__tests__/getOrCreateSandbox.test.ts index eabcd2a..b76550b 100644 --- a/src/sandboxes/__tests__/getOrCreateSandbox.test.ts +++ b/src/sandboxes/__tests__/getOrCreateSandbox.test.ts @@ -15,9 +15,7 @@ vi.mock("@vercel/sandbox", () => ({ })); vi.mock("../../recoup/createAccountSandbox", () => ({ - createAccountSandbox: vi - .fn() - .mockResolvedValue({ sandboxId: "sbx_123" }), + createAccountSandbox: vi.fn().mockResolvedValue({ sandboxId: "sbx_123" }), })); vi.mock("../getVercelSandboxCredentials", () => ({ @@ -34,9 +32,7 @@ vi.mock("../logStep", () => ({ const { getOrCreateSandbox } = await import("../getOrCreateSandbox"); const { Sandbox } = await import("@vercel/sandbox"); -const { createAccountSandbox } = await import( - "../../recoup/createAccountSandbox" -); +const { createAccountSandbox } = await import("../../recoup/createAccountSandbox"); beforeEach(() => { vi.clearAllMocks(); @@ -52,18 +48,14 @@ describe("getOrCreateSandbox", () => { it("connects to sandbox via Sandbox.get with returned sandboxId", async () => { await getOrCreateSandbox("acc_1"); - expect(Sandbox.get).toHaveBeenCalledWith( - expect.objectContaining({ sandboxId: "sbx_123" }), - ); + expect(Sandbox.get).toHaveBeenCalledWith(expect.objectContaining({ sandboxId: "sbx_123" })); }); it("returns sandboxId and sandbox instance", async () => { const result = await getOrCreateSandbox("acc_1"); expect(result.sandboxId).toBe("sbx_123"); - expect(result.sandbox).toEqual( - expect.objectContaining({ sandboxId: "sbx_123" }), - ); + expect(result.sandbox).toEqual(expect.objectContaining({ sandboxId: "sbx_123" })); }); it("throws when createAccountSandbox returns undefined", async () => { diff --git a/src/sandboxes/__tests__/getSandboxHomeDir.test.ts b/src/sandboxes/__tests__/getSandboxHomeDir.test.ts index f5dcbc0..683f007 100644 --- a/src/sandboxes/__tests__/getSandboxHomeDir.test.ts +++ b/src/sandboxes/__tests__/getSandboxHomeDir.test.ts @@ -1,6 +1,10 @@ import { describe, it, expect, vi } from "vitest"; import { getSandboxHomeDir } from "../getSandboxHomeDir"; +/** + * + * @param stdout + */ function createMockSandbox(stdout = "/home/user") { return { runCommand: vi.fn().mockResolvedValue({ diff --git a/src/sandboxes/__tests__/notifyCodingAgentCallback.test.ts b/src/sandboxes/__tests__/notifyCodingAgentCallback.test.ts index aff093c..59d9373 100644 --- a/src/sandboxes/__tests__/notifyCodingAgentCallback.test.ts +++ b/src/sandboxes/__tests__/notifyCodingAgentCallback.test.ts @@ -52,9 +52,7 @@ describe("notifyCodingAgentCallback", () => { status: "no_changes", }); - expect(logger.error).toHaveBeenCalledWith( - expect.stringContaining("CODING_AGENT_CALLBACK_URL"), - ); + expect(logger.error).toHaveBeenCalledWith(expect.stringContaining("CODING_AGENT_CALLBACK_URL")); expect(mockFetch).not.toHaveBeenCalled(); }); }); diff --git a/src/sandboxes/__tests__/pushOrgRepos.test.ts b/src/sandboxes/__tests__/pushOrgRepos.test.ts index f0c2d2b..0934661 100644 --- a/src/sandboxes/__tests__/pushOrgRepos.test.ts +++ b/src/sandboxes/__tests__/pushOrgRepos.test.ts @@ -16,6 +16,9 @@ vi.mock("../logStep", () => ({ const { pushOrgRepos } = await import("../git/pushOrgRepos"); const { logStep } = await import("../logStep"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn(); return { runCommand } as any; @@ -54,7 +57,7 @@ describe("pushOrgRepos", () => { // Should not call openclaw const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); expect(openclawCall).toBeUndefined(); }); @@ -81,7 +84,7 @@ describe("pushOrgRepos", () => { call[0]?.args?.[0] === "agent" && call[0]?.args?.[1] === "--agent" && call[0]?.args?.[2] === "main" && - call[0]?.args?.[3] === "--message" + call[0]?.args?.[3] === "--message", ); expect(openclawCall).toBeDefined(); @@ -112,7 +115,7 @@ describe("pushOrgRepos", () => { await pushOrgRepos(sandbox); const openclawCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => call[0]?.cmd === "openclaw" + (call: any[]) => call[0]?.cmd === "openclaw", ); const message = openclawCall![0].args[4]; @@ -147,8 +150,7 @@ describe("pushOrgRepos", () => { // The find command should use resolved path, not ~ const findCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("find") + (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("find"), ); expect(findCall![0].args[1]).toContain("/home/sandbox/"); expect(findCall![0].args[1]).not.toContain("~"); @@ -182,7 +184,7 @@ describe("pushOrgRepos", () => { expect(logStep).toHaveBeenCalledWith( expect.stringContaining("failed"), false, - expect.objectContaining({ stderr: expect.any(String) }) + expect.objectContaining({ stderr: expect.any(String) }), ); }); }); diff --git a/src/sandboxes/__tests__/runOpenClawAgent.test.ts b/src/sandboxes/__tests__/runOpenClawAgent.test.ts index 8f98453..65dd7f8 100644 --- a/src/sandboxes/__tests__/runOpenClawAgent.test.ts +++ b/src/sandboxes/__tests__/runOpenClawAgent.test.ts @@ -12,6 +12,9 @@ vi.mock("../logStep", () => ({ const { runOpenClawAgent } = await import("../runOpenClawAgent"); const { logStep } = await import("../logStep"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn(); return { runCommand } as any; @@ -136,5 +139,4 @@ describe("runOpenClawAgent", () => { expect(result.stdout).toBe("output\n"); expect(result.stderr).toBe("warn\n"); }); - }); diff --git a/src/sandboxes/__tests__/setupOpenClaw.test.ts b/src/sandboxes/__tests__/setupOpenClaw.test.ts index 8b7077d..0da4615 100644 --- a/src/sandboxes/__tests__/setupOpenClaw.test.ts +++ b/src/sandboxes/__tests__/setupOpenClaw.test.ts @@ -10,6 +10,9 @@ vi.mock("../onboardOpenClaw", () => ({ const { setupOpenClaw } = await import("../setupOpenClaw"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0, @@ -31,9 +34,7 @@ describe("setupOpenClaw", () => { delete process.env.RECOUP_API_KEY; const sandbox = createMockSandbox(); - await expect(setupOpenClaw(sandbox, "account-1")).rejects.toThrow( - "Missing RECOUP_API_KEY" - ); + await expect(setupOpenClaw(sandbox, "account-1")).rejects.toThrow("Missing RECOUP_API_KEY"); }); it("injects RECOUP_API_KEY and RECOUP_ACCOUNT_ID into openclaw.json", async () => { @@ -42,12 +43,10 @@ describe("setupOpenClaw", () => { await setupOpenClaw(sandbox, "account-1"); // Find the node -e call that injects env vars - const injectCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => { - const args = call[0]?.args; - return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); - } - ); + const injectCall = sandbox.runCommand.mock.calls.find((call: any[]) => { + const args = call[0]?.args; + return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); + }); expect(injectCall).toBeDefined(); const script = injectCall![0].args[1]; @@ -71,12 +70,10 @@ describe("setupOpenClaw", () => { await setupOpenClaw(sandbox, "account-1"); // Find the node -e call that injects env vars - const injectCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => { - const args = call[0]?.args; - return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); - } - ); + const injectCall = sandbox.runCommand.mock.calls.find((call: any[]) => { + const args = call[0]?.args; + return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); + }); expect(injectCall).toBeDefined(); const script = injectCall![0].args[1]; @@ -92,12 +89,10 @@ describe("setupOpenClaw", () => { await setupOpenClaw(sandbox, "account-1"); // Env injection call should still run (for RECOUP vars) - const injectCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => { - const args = call[0]?.args; - return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); - } - ); + const injectCall = sandbox.runCommand.mock.calls.find((call: any[]) => { + const args = call[0]?.args; + return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); + }); expect(injectCall).toBeDefined(); }); @@ -106,12 +101,10 @@ describe("setupOpenClaw", () => { await setupOpenClaw(sandbox, "account-1"); - const injectCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => { - const args = call[0]?.args; - return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); - } - ); + const injectCall = sandbox.runCommand.mock.calls.find((call: any[]) => { + const args = call[0]?.args; + return args?.[0] === "-c" && args?.[1]?.includes("openclaw.json"); + }); expect(injectCall).toBeDefined(); const script = injectCall![0].args[1]; @@ -125,12 +118,10 @@ describe("setupOpenClaw", () => { await setupOpenClaw(sandbox, "account-1"); // Find the gateway start call - const gatewayCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => { - const args = call[0]?.args; - return args?.[1]?.includes("gateway"); - } - ); + const gatewayCall = sandbox.runCommand.mock.calls.find((call: any[]) => { + const args = call[0]?.args; + return args?.[1]?.includes("gateway"); + }); expect(gatewayCall).toBeDefined(); }); @@ -140,15 +131,12 @@ describe("setupOpenClaw", () => { // Make the second runCommand call (env injection) fail // First call is onboardOpenClaw (mocked), so first runCommand is env injection - sandbox.runCommand - .mockResolvedValueOnce({ - exitCode: 1, - stdout: async () => "", - stderr: async () => "node script failed", - }); - - await expect(setupOpenClaw(sandbox, "account-1")).rejects.toThrow( - "Failed to inject env vars" - ); + sandbox.runCommand.mockResolvedValueOnce({ + exitCode: 1, + stdout: async () => "", + stderr: async () => "node script failed", + }); + + await expect(setupOpenClaw(sandbox, "account-1")).rejects.toThrow("Failed to inject env vars"); }); }); diff --git a/src/sandboxes/__tests__/snapshotAndPersist.test.ts b/src/sandboxes/__tests__/snapshotAndPersist.test.ts index 8876697..74bf0e9 100644 --- a/src/sandboxes/__tests__/snapshotAndPersist.test.ts +++ b/src/sandboxes/__tests__/snapshotAndPersist.test.ts @@ -12,6 +12,9 @@ const { snapshotAndPersist } = await import("../snapshotAndPersist"); const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000; +/** + * + */ function createMockSandbox() { return { snapshot: vi.fn().mockResolvedValue({ diff --git a/src/sandboxes/__tests__/stripGitmodulesTokens.test.ts b/src/sandboxes/__tests__/stripGitmodulesTokens.test.ts index 4ba7512..c234490 100644 --- a/src/sandboxes/__tests__/stripGitmodulesTokens.test.ts +++ b/src/sandboxes/__tests__/stripGitmodulesTokens.test.ts @@ -6,6 +6,9 @@ vi.mock("@trigger.dev/sdk/v3", () => ({ const { stripGitmodulesTokens } = await import("../git/stripGitmodulesTokens"); +/** + * + */ function createMockSandbox() { const runCommand = vi.fn().mockResolvedValue({ exitCode: 0, @@ -29,7 +32,7 @@ describe("stripGitmodulesTokens", () => { (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes("x-access-token") && - call[0]?.args?.[1]?.includes(".gitmodules") + call[0]?.args?.[1]?.includes(".gitmodules"), ); expect(sedCall).toBeDefined(); @@ -43,9 +46,7 @@ describe("stripGitmodulesTokens", () => { await stripGitmodulesTokens(sandbox); const sedCall = sandbox.runCommand.mock.calls.find( - (call: any[]) => - call[0]?.cmd === "sh" && - call[0]?.args?.[1]?.includes(".gitmodules") + (call: any[]) => call[0]?.cmd === "sh" && call[0]?.args?.[1]?.includes(".gitmodules"), ); const cmd = sedCall![0].args[1]; expect(cmd).toContain("git add .gitmodules"); diff --git a/src/sandboxes/cloneMonorepoViaAgent.ts b/src/sandboxes/cloneMonorepoViaAgent.ts index 1dd257d..777375b 100644 --- a/src/sandboxes/cloneMonorepoViaAgent.ts +++ b/src/sandboxes/cloneMonorepoViaAgent.ts @@ -8,9 +8,7 @@ import { runOpenClawAgent } from "./runOpenClawAgent"; * * @param sandbox - The Vercel Sandbox instance */ -export async function cloneMonorepoViaAgent( - sandbox: Sandbox, -): Promise { +export async function cloneMonorepoViaAgent(sandbox: Sandbox): Promise { await runOpenClawAgent(sandbox, { label: "Clone monorepo via agent", message: [ diff --git a/src/sandboxes/configureGitAuth.ts b/src/sandboxes/configureGitAuth.ts index abf9ebe..aac63fb 100644 --- a/src/sandboxes/configureGitAuth.ts +++ b/src/sandboxes/configureGitAuth.ts @@ -7,6 +7,8 @@ import { getGitHubAuthPrefix } from "./getGitHubAuthPrefix"; * * Sets url.insteadOf so all HTTPS GitHub URLs automatically use the token, * and configures the Recoup Agent git identity. + * + * @param sandbox */ export async function configureGitAuth(sandbox: Sandbox): Promise { const authPrefix = getGitHubAuthPrefix(); @@ -14,12 +16,7 @@ export async function configureGitAuth(sandbox: Sandbox): Promise { if (authPrefix) { await sandbox.runCommand({ cmd: "git", - args: [ - "config", - "--global", - `url.${authPrefix}.insteadOf`, - "https://github.com/", - ], + args: ["config", "--global", `url.${authPrefix}.insteadOf`, "https://github.com/"], }); logger.log("Git auth configured with GITHUB_TOKEN"); } else { diff --git a/src/sandboxes/ensureGithubRepo.ts b/src/sandboxes/ensureGithubRepo.ts index 73b9f27..b3a7564 100644 --- a/src/sandboxes/ensureGithubRepo.ts +++ b/src/sandboxes/ensureGithubRepo.ts @@ -21,7 +21,7 @@ import { getGitHubAuthPrefix } from "./getGitHubAuthPrefix"; */ export async function ensureGithubRepo( sandbox: Sandbox, - accountId: string + accountId: string, ): Promise { const authPrefix = getGitHubAuthPrefix(); @@ -80,13 +80,7 @@ export async function ensureGithubRepo( return undefined; } - if ( - !(await runGitCommand( - sandbox, - ["remote", "add", "origin", repoUrl], - "add remote" - )) - ) { + if (!(await runGitCommand(sandbox, ["remote", "add", "origin", repoUrl], "add remote"))) { return undefined; } @@ -108,7 +102,7 @@ export async function ensureGithubRepo( !(await runGitCommand( sandbox, ["checkout", "-B", "main", "origin/main"], - "checkout main branch" + "checkout main branch", )) ) { return undefined; @@ -117,11 +111,7 @@ export async function ensureGithubRepo( // Set up URL rewriting so submodule clones use auth await sandbox.runCommand({ cmd: "git", - args: [ - "config", - `url.${authPrefix}.insteadOf`, - "https://github.com/", - ], + args: ["config", `url.${authPrefix}.insteadOf`, "https://github.com/"], }); // Initialize submodules if they exist (org repos) diff --git a/src/sandboxes/ensureOrgRepos.ts b/src/sandboxes/ensureOrgRepos.ts index 512c4c7..288e926 100644 --- a/src/sandboxes/ensureOrgRepos.ts +++ b/src/sandboxes/ensureOrgRepos.ts @@ -16,10 +16,7 @@ import { logStep } from "./logStep"; * @param sandbox - The Vercel Sandbox instance * @param accountId - The account ID to look up orgs for */ -export async function ensureOrgRepos( - sandbox: Sandbox, - accountId: string -): Promise { +export async function ensureOrgRepos(sandbox: Sandbox, accountId: string): Promise { const githubToken = process.env.GITHUB_TOKEN; if (!githubToken) { @@ -41,10 +38,7 @@ export async function ensureOrgRepos( const orgRepos: Array<{ name: string; url: string }> = []; for (const org of orgs) { - const repoUrl = await createOrgGithubRepo( - org.organizationName, - org.organizationId - ); + const repoUrl = await createOrgGithubRepo(org.organizationName, org.organizationId); if (!repoUrl) { logger.error("Failed to create org GitHub repo, skipping", { @@ -66,9 +60,7 @@ export async function ensureOrgRepos( } // Build the prompt for OpenClaw to clone the repos - const repoList = orgRepos - .map((r) => `- "${r.name}" → ${r.url}`) - .join("\n"); + const repoList = orgRepos.map(r => `- "${r.name}" → ${r.url}`).join("\n"); const message = [ "Clone the following GitHub repositories into orgs/ in your workspace.", diff --git a/src/sandboxes/ensureSetupSandbox.ts b/src/sandboxes/ensureSetupSandbox.ts index f0ad567..b24a75f 100644 --- a/src/sandboxes/ensureSetupSandbox.ts +++ b/src/sandboxes/ensureSetupSandbox.ts @@ -11,10 +11,7 @@ import { logStep } from "./logStep"; * @param sandbox - The Vercel Sandbox instance * @param accountId - The account ID for the sandbox owner */ -export async function ensureSetupSandbox( - sandbox: Sandbox, - accountId: string -): Promise { +export async function ensureSetupSandbox(sandbox: Sandbox, accountId: string): Promise { logStep("Installing skills"); await installSkill(sandbox, "recoupable/setup-sandbox"); diff --git a/src/sandboxes/getOrCreateSandbox.ts b/src/sandboxes/getOrCreateSandbox.ts index 8eb716b..43b4ccb 100644 --- a/src/sandboxes/getOrCreateSandbox.ts +++ b/src/sandboxes/getOrCreateSandbox.ts @@ -15,9 +15,7 @@ interface GetOrCreateSandboxResult { * @param accountId - The account ID to create a sandbox for * @returns The sandbox ID and connected Sandbox instance */ -export async function getOrCreateSandbox( - accountId: string, -): Promise { +export async function getOrCreateSandbox(accountId: string): Promise { const { token, teamId, projectId } = getVercelSandboxCredentials(); logStep("Creating sandbox via API"); diff --git a/src/sandboxes/getSandboxEnv.ts b/src/sandboxes/getSandboxEnv.ts index 3906254..421a527 100644 --- a/src/sandboxes/getSandboxEnv.ts +++ b/src/sandboxes/getSandboxEnv.ts @@ -1,10 +1,10 @@ /** * Builds the environment variables to inject into sandbox commands. * Shared by runSandboxCommandTask and codingAgentTask. + * + * @param accountId */ -export function getSandboxEnv( - accountId: string -): Record { +export function getSandboxEnv(accountId: string): Record { const apiKey = process.env.RECOUP_API_KEY; if (!apiKey) { throw new Error("Missing RECOUP_API_KEY environment variable"); diff --git a/src/sandboxes/getVercelSandboxCredentials.ts b/src/sandboxes/getVercelSandboxCredentials.ts index ca42463..0e18a2d 100644 --- a/src/sandboxes/getVercelSandboxCredentials.ts +++ b/src/sandboxes/getVercelSandboxCredentials.ts @@ -10,7 +10,7 @@ export function getVercelSandboxCredentials() { if (!token || !teamId || !projectId) { throw new Error( - "Missing Vercel credentials. Set VERCEL_TOKEN, VERCEL_TEAM_ID, and VERCEL_PROJECT_ID." + "Missing Vercel credentials. Set VERCEL_TOKEN, VERCEL_TEAM_ID, and VERCEL_PROJECT_ID.", ); } diff --git a/src/sandboxes/git/addOrgSubmodules.ts b/src/sandboxes/git/addOrgSubmodules.ts index 7770f77..198001d 100644 --- a/src/sandboxes/git/addOrgSubmodules.ts +++ b/src/sandboxes/git/addOrgSubmodules.ts @@ -32,7 +32,7 @@ export async function addOrgSubmodules(sandbox: Sandbox): Promise { const stdout = (await findResult.stdout()) || ""; const orgNames = stdout .split("\n") - .map((s) => s.trim()) + .map(s => s.trim()) .filter(Boolean); if (orgNames.length === 0) { diff --git a/src/sandboxes/git/pushOrgRepos.ts b/src/sandboxes/git/pushOrgRepos.ts index 969a4f6..9451b79 100644 --- a/src/sandboxes/git/pushOrgRepos.ts +++ b/src/sandboxes/git/pushOrgRepos.ts @@ -12,9 +12,7 @@ import { getSandboxHomeDir } from "../getSandboxHomeDir"; * * @param sandbox - The Vercel Sandbox instance */ -export async function pushOrgRepos( - sandbox: Sandbox -): Promise { +export async function pushOrgRepos(sandbox: Sandbox): Promise { const githubToken = process.env.GITHUB_TOKEN; if (!githubToken) { @@ -37,7 +35,7 @@ export async function pushOrgRepos( const stdout = (await findResult.stdout()) || ""; const orgNames = stdout .split("\n") - .map((s) => s.trim()) + .map(s => s.trim()) .filter(Boolean); if (orgNames.length === 0) { diff --git a/src/sandboxes/installSkill.ts b/src/sandboxes/installSkill.ts index b016d14..12ccbce 100644 --- a/src/sandboxes/installSkill.ts +++ b/src/sandboxes/installSkill.ts @@ -10,10 +10,7 @@ import { logger } from "@trigger.dev/sdk/v3"; * @param sandbox - The Vercel Sandbox instance * @param skill - The skills.sh skill identifier (e.g. "recoupable/setup-sandbox") */ -export async function installSkill( - sandbox: Sandbox, - skill: string -): Promise { +export async function installSkill(sandbox: Sandbox, skill: string): Promise { const skillName = skill.split("/").pop()!; logger.log("Installing skill via skills.sh", { skill }); diff --git a/src/sandboxes/logStep.ts b/src/sandboxes/logStep.ts index f166f99..7b8c2d2 100644 --- a/src/sandboxes/logStep.ts +++ b/src/sandboxes/logStep.ts @@ -8,11 +8,7 @@ import { logger, metadata } from "@trigger.dev/sdk/v3"; * @param isStep - If true, also sets currentStep metadata (default: true) * @param extra - Optional JSON object included in logger.log but NOT in metadata */ -export function logStep( - message: string, - isStep = true, - extra?: Record, -): void { +export function logStep(message: string, isStep = true, extra?: Record): void { if (isStep) { metadata.set("currentStep", message); } diff --git a/src/sandboxes/notifyCodingAgentCallback.ts b/src/sandboxes/notifyCodingAgentCallback.ts index b676780..065c64c 100644 --- a/src/sandboxes/notifyCodingAgentCallback.ts +++ b/src/sandboxes/notifyCodingAgentCallback.ts @@ -26,7 +26,10 @@ export async function notifyCodingAgentCallback(payload: CallbackPayload): Promi return; } - logger.log("Sending coding agent callback", { threadId: payload.threadId, status: payload.status }); + logger.log("Sending coding agent callback", { + threadId: payload.threadId, + status: payload.status, + }); try { const response = await fetch(url, { diff --git a/src/sandboxes/onboardOpenClaw.ts b/src/sandboxes/onboardOpenClaw.ts index c450f93..27ba42a 100644 --- a/src/sandboxes/onboardOpenClaw.ts +++ b/src/sandboxes/onboardOpenClaw.ts @@ -35,7 +35,7 @@ export async function onboardOpenClaw(sandbox: Sandbox): Promise { ]; logger.log("Running OpenClaw onboard", { - command: `openclaw ${onboardArgs.map((a) => (a === process.env.VERCEL_AI_GATEWAY_API_KEY ? "[REDACTED]" : a)).join(" ")}`, + command: `openclaw ${onboardArgs.map(a => (a === process.env.VERCEL_AI_GATEWAY_API_KEY ? "[REDACTED]" : a)).join(" ")}`, }); const onboard = await sandbox.runCommand({ diff --git a/src/sandboxes/parsePRUrls.ts b/src/sandboxes/parsePRUrls.ts index 5d0be6c..d08b430 100644 --- a/src/sandboxes/parsePRUrls.ts +++ b/src/sandboxes/parsePRUrls.ts @@ -19,7 +19,9 @@ export function parsePRUrls(stdout: string): ParsedPR[] { const prs: ParsedPR[] = []; for (const line of lines) { - const match = line.match(/^PR_CREATED:\s*(https:\/\/github\.com\/([^/]+\/[^/]+)\/pull\/(\d+))\s*$/); + const match = line.match( + /^PR_CREATED:\s*(https:\/\/github\.com\/([^/]+\/[^/]+)\/pull\/(\d+))\s*$/, + ); if (!match) continue; const url = match[1]; @@ -27,7 +29,7 @@ export function parsePRUrls(stdout: string): ParsedPR[] { const number = parseInt(match[3], 10); // Look up baseBranch from SUBMODULE_CONFIG by matching the repo - const configEntry = Object.values(SUBMODULE_CONFIG).find((c) => c.repo === repo); + const configEntry = Object.values(SUBMODULE_CONFIG).find(c => c.repo === repo); const baseBranch = configEntry?.baseBranch ?? "main"; prs.push({ repo, number, url, baseBranch }); diff --git a/src/sandboxes/pushSandboxToGithub.ts b/src/sandboxes/pushSandboxToGithub.ts index 4f711b6..3defd23 100644 --- a/src/sandboxes/pushSandboxToGithub.ts +++ b/src/sandboxes/pushSandboxToGithub.ts @@ -15,9 +15,7 @@ import { pushOrgRepos } from "./git/pushOrgRepos"; * @param sandbox - The Vercel Sandbox instance * @returns true if push succeeded or there were no changes, false on error */ -export async function pushSandboxToGithub( - sandbox: Sandbox -): Promise { +export async function pushSandboxToGithub(sandbox: Sandbox): Promise { logger.log("Pushing sandbox files to GitHub"); // Configure git user for commits @@ -25,18 +23,14 @@ export async function pushSandboxToGithub( !(await runGitCommand( sandbox, ["config", "user.email", "agent@recoupable.com"], - "configure git email" + "configure git email", )) ) { return false; } if ( - !(await runGitCommand( - sandbox, - ["config", "user.name", "Recoup Agent"], - "configure git name" - )) + !(await runGitCommand(sandbox, ["config", "user.name", "Recoup Agent"], "configure git name")) ) { return false; } @@ -67,11 +61,7 @@ export async function pushSandboxToGithub( if (diffResult.exitCode !== 0) { // There are staged changes — commit them if ( - !(await runGitCommand( - sandbox, - ["commit", "-m", "Update sandbox files"], - "commit changes" - )) + !(await runGitCommand(sandbox, ["commit", "-m", "Update sandbox files"], "commit changes")) ) { return false; } @@ -82,11 +72,7 @@ export async function pushSandboxToGithub( // Force push — sandbox files are the source of truth if ( - !(await runGitCommand( - sandbox, - ["push", "--force", "origin", "HEAD:main"], - "push to remote" - )) + !(await runGitCommand(sandbox, ["push", "--force", "origin", "HEAD:main"], "push to remote")) ) { return false; } diff --git a/src/sandboxes/runGitCommand.ts b/src/sandboxes/runGitCommand.ts index 1e99b6e..21ceb01 100644 --- a/src/sandboxes/runGitCommand.ts +++ b/src/sandboxes/runGitCommand.ts @@ -4,12 +4,15 @@ import { logger } from "@trigger.dev/sdk/v3"; /** * Runs a git command in the sandbox and logs stderr on failure. * + * @param sandbox + * @param args + * @param description * @returns true if the command succeeded, false otherwise */ export async function runGitCommand( sandbox: Sandbox, args: string[], - description: string + description: string, ): Promise { const result = await sandbox.runCommand({ cmd: "git", args }); diff --git a/src/sandboxes/runOpenClawAgent.ts b/src/sandboxes/runOpenClawAgent.ts index 1f617d7..42eb5fb 100644 --- a/src/sandboxes/runOpenClawAgent.ts +++ b/src/sandboxes/runOpenClawAgent.ts @@ -22,7 +22,7 @@ interface RunOpenClawAgentResult { */ export async function runOpenClawAgent( sandbox: Sandbox, - options: RunOpenClawAgentOptions + options: RunOpenClawAgentOptions, ): Promise { const { label, message, env } = options; diff --git a/src/sandboxes/runSetupArtistSkill.ts b/src/sandboxes/runSetupArtistSkill.ts index b5956f9..eac7aa5 100644 --- a/src/sandboxes/runSetupArtistSkill.ts +++ b/src/sandboxes/runSetupArtistSkill.ts @@ -10,7 +10,7 @@ import { runOpenClawAgent } from "./runOpenClawAgent"; */ export async function runSetupArtistSkill( sandbox: Sandbox, - env: Record + env: Record, ): Promise { const result = await runOpenClawAgent(sandbox, { label: "Running setup-artist skill", diff --git a/src/sandboxes/runSetupSandboxSkill.ts b/src/sandboxes/runSetupSandboxSkill.ts index 7ea296a..77eacc5 100644 --- a/src/sandboxes/runSetupSandboxSkill.ts +++ b/src/sandboxes/runSetupSandboxSkill.ts @@ -10,7 +10,7 @@ import { runOpenClawAgent } from "./runOpenClawAgent"; */ export async function runSetupSandboxSkill( sandbox: Sandbox, - env: Record + env: Record, ): Promise { const result = await runOpenClawAgent(sandbox, { label: "Running setup-sandbox skill", diff --git a/src/sandboxes/setupOpenClaw.ts b/src/sandboxes/setupOpenClaw.ts index dc95b59..b2cd793 100644 --- a/src/sandboxes/setupOpenClaw.ts +++ b/src/sandboxes/setupOpenClaw.ts @@ -10,10 +10,7 @@ import { onboardOpenClaw } from "./onboardOpenClaw"; * @param accountId - The account ID for the sandbox owner * @throws Error if env injection or gateway startup fails */ -export async function setupOpenClaw( - sandbox: Sandbox, - accountId: string -): Promise { +export async function setupOpenClaw(sandbox: Sandbox, accountId: string): Promise { await onboardOpenClaw(sandbox); // Inject RECOUP env vars into openclaw.json's env block so they're diff --git a/src/sandboxes/snapshotAndPersist.ts b/src/sandboxes/snapshotAndPersist.ts index 56b36b3..868c81a 100644 --- a/src/sandboxes/snapshotAndPersist.ts +++ b/src/sandboxes/snapshotAndPersist.ts @@ -11,11 +11,7 @@ import { updateAccountSnapshot } from "../recoup/updateAccountSnapshot"; * @param githubRepo - Optional GitHub repo URL to persist alongside the snapshot * @returns The snapshot result with snapshotId and expiresAt */ -export async function snapshotAndPersist( - sandbox: Sandbox, - accountId: string, - githubRepo?: string -) { +export async function snapshotAndPersist(sandbox: Sandbox, accountId: string, githubRepo?: string) { const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000; logger.log("Taking sandbox snapshot"); diff --git a/src/sandboxes/writeReadme.ts b/src/sandboxes/writeReadme.ts index 536f031..4c0b69b 100644 --- a/src/sandboxes/writeReadme.ts +++ b/src/sandboxes/writeReadme.ts @@ -16,7 +16,7 @@ export async function writeReadme( sandbox: Sandbox, sandboxId: string, accountId: string, - githubRepo?: string + githubRepo?: string, ): Promise { // Skip if README.md already has our content const check = await sandbox.runCommand({ diff --git a/src/schemas/sandboxSchema.ts b/src/schemas/sandboxSchema.ts index 943eeea..77c6fd6 100644 --- a/src/schemas/sandboxSchema.ts +++ b/src/schemas/sandboxSchema.ts @@ -8,9 +8,7 @@ export const runSandboxCommandPayloadSchema = z.object({ accountId: z.string().min(1, "accountId is required"), }); -export type RunSandboxCommandPayload = z.infer< - typeof runSandboxCommandPayloadSchema ->; +export type RunSandboxCommandPayload = z.infer; export const snapshotSchema = z.object({ id: z.string(), diff --git a/src/socials/filterScrapableSocials.ts b/src/socials/filterScrapableSocials.ts index 610fbee..80b8393 100644 --- a/src/socials/filterScrapableSocials.ts +++ b/src/socials/filterScrapableSocials.ts @@ -12,13 +12,13 @@ export type ScrapableSocial = { /** * Filters and collects all scrapable socials from the artist socials map. * Returns an array of scrapable socials with their associated artist IDs. + * + * @param artistIds + * @param artistSocialsMap */ export function filterScrapableSocials( artistIds: string[], - artistSocialsMap: Map< - string, - Awaited> | undefined - > + artistSocialsMap: Map> | undefined>, ): ScrapableSocial[] { const scrapableSocials: ScrapableSocial[] = []; const nonScrapableSocials: Array<{ diff --git a/src/socials/scrapeAndPollSocials.ts b/src/socials/scrapeAndPollSocials.ts index 860f8f9..f0e98b8 100644 --- a/src/socials/scrapeAndPollSocials.ts +++ b/src/socials/scrapeAndPollSocials.ts @@ -9,10 +9,13 @@ export const SCRAPE_BATCH_SIZE = 10; /** * Scrapes and polls socials in batches, waiting for each batch to complete before starting the next. * Returns an array of poll results for all completed scrapes. + * + * @param socials + * @param batchSize */ export async function scrapeAndPollSocials( socials: ScrapableSocial[], - batchSize: number = SCRAPE_BATCH_SIZE + batchSize: number = SCRAPE_BATCH_SIZE, ): Promise { const allResults: PollResult[] = []; @@ -23,7 +26,7 @@ export async function scrapeAndPollSocials( // Start scrapes for this batch const scrapeResults = await Promise.all( - socialBatch.map((social) => scrapeSocial(social.socialId)) + socialBatch.map(social => scrapeSocial(social.socialId)), ); // Collect valid runs from this batch @@ -75,27 +78,24 @@ export async function scrapeAndPollSocials( // Log all successfully started scrapes for this batch if (startedScrapes.length > 0) { - logger.log( - `Started scrapes for batch ${batchNumber} of ${totalBatches}`, - { - count: startedScrapes.length, - scrapes: startedScrapes, - } - ); + logger.log(`Started scrapes for batch ${batchNumber} of ${totalBatches}`, { + count: startedScrapes.length, + scrapes: startedScrapes, + }); } // Poll this batch to completion before moving to next batch logger.log(`Polling batch ${batchNumber} runs to completion`, { batchRuns: batchRuns.length, - runIds: batchRuns.map((r) => r.runId), + runIds: batchRuns.map(r => r.runId), }); const batchResults = await pollScraperResults(batchRuns); logger.log(`Batch ${batchNumber} completed`, { total: batchResults.length, - succeeded: batchResults.filter((r) => r.status === "SUCCEEDED").length, - failed: batchResults.filter((r) => r.status === "FAILED").length, + succeeded: batchResults.filter(r => r.status === "SUCCEEDED").length, + failed: batchResults.filter(r => r.status === "FAILED").length, results: batchResults, }); diff --git a/src/tasks/__tests__/codingAgentTask.test.ts b/src/tasks/__tests__/codingAgentTask.test.ts index 3e4fc4e..93ce474 100644 --- a/src/tasks/__tests__/codingAgentTask.test.ts +++ b/src/tasks/__tests__/codingAgentTask.test.ts @@ -23,7 +23,9 @@ vi.mock("@vercel/sandbox", () => ({ vi.mock("../../sandboxes/getVercelSandboxCredentials", () => ({ getVercelSandboxCredentials: vi.fn().mockReturnValue({ - token: "tok", teamId: "team", projectId: "proj", + token: "tok", + teamId: "team", + projectId: "proj", }), })); @@ -50,8 +52,10 @@ vi.mock("../../sandboxes/runOpenClawAgent", () => ({ vi.mock("../../sandboxes/pushAndCreatePRsViaAgent", () => ({ pushAndCreatePRsViaAgent: vi.fn().mockResolvedValue([ { - repo: "recoupable/api", number: 42, - url: "https://github.com/recoupable/api/pull/42", baseBranch: "test", + repo: "recoupable/api", + number: 42, + url: "https://github.com/recoupable/api/pull/42", + baseBranch: "test", }, ]), })); @@ -140,5 +144,4 @@ describe("codingAgentTask", () => { expect(configureGitAuth).toHaveBeenCalledOnce(); }); - }); diff --git a/src/tasks/__tests__/sendPulsesTask.test.ts b/src/tasks/__tests__/sendPulsesTask.test.ts index 52ff3a7..fae60d6 100644 --- a/src/tasks/__tests__/sendPulsesTask.test.ts +++ b/src/tasks/__tests__/sendPulsesTask.test.ts @@ -20,8 +20,7 @@ vi.mock("../../recoup/fetchActivePulses", () => ({ const mockExecutePulseInSandbox = vi.fn(); vi.mock("../../pulse/executePulseInSandbox", () => ({ - executePulseInSandbox: (...args: unknown[]) => - mockExecutePulseInSandbox(...args), + executePulseInSandbox: (...args: unknown[]) => mockExecutePulseInSandbox(...args), })); // Import after mocks @@ -53,7 +52,7 @@ describe("sendPulsesTask", () => { expect.objectContaining({ accountId: "account-1", prompt: expect.any(String), - }) + }), ); }); diff --git a/src/tasks/__tests__/setupSandboxTask.test.ts b/src/tasks/__tests__/setupSandboxTask.test.ts index f9baed5..323f164 100644 --- a/src/tasks/__tests__/setupSandboxTask.test.ts +++ b/src/tasks/__tests__/setupSandboxTask.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("@trigger.dev/sdk/v3", () => ({ logger: { log: vi.fn(), error: vi.fn() }, - schemaTask: vi.fn((config) => config), + schemaTask: vi.fn(config => config), })); const mockStop = vi.fn().mockResolvedValue(undefined); @@ -23,9 +23,7 @@ vi.mock("../../sandboxes/logStep", () => ({ })); vi.mock("../../sandboxes/provisionSandbox", () => ({ - provisionSandbox: vi - .fn() - .mockResolvedValue({ githubRepo: "https://github.com/org/repo" }), + provisionSandbox: vi.fn().mockResolvedValue({ githubRepo: "https://github.com/org/repo" }), })); vi.mock("../../sandboxes/snapshotAndPersist", () => ({ @@ -36,15 +34,9 @@ vi.mock("../../sandboxes/snapshotAndPersist", () => ({ })); const { setupSandboxTask } = await import("../setupSandboxTask"); -const { getOrCreateSandbox } = await import( - "../../sandboxes/getOrCreateSandbox" -); -const { provisionSandbox } = await import( - "../../sandboxes/provisionSandbox" -); -const { snapshotAndPersist } = await import( - "../../sandboxes/snapshotAndPersist" -); +const { getOrCreateSandbox } = await import("../../sandboxes/getOrCreateSandbox"); +const { provisionSandbox } = await import("../../sandboxes/provisionSandbox"); +const { snapshotAndPersist } = await import("../../sandboxes/snapshotAndPersist"); beforeEach(() => { vi.clearAllMocks(); diff --git a/src/tasks/__tests__/updatePRTask.test.ts b/src/tasks/__tests__/updatePRTask.test.ts index 483b565..db82fa6 100644 --- a/src/tasks/__tests__/updatePRTask.test.ts +++ b/src/tasks/__tests__/updatePRTask.test.ts @@ -23,7 +23,9 @@ vi.mock("@vercel/sandbox", () => ({ vi.mock("../../sandboxes/getVercelSandboxCredentials", () => ({ getVercelSandboxCredentials: vi.fn().mockReturnValue({ - token: "tok", teamId: "team", projectId: "proj", + token: "tok", + teamId: "team", + projectId: "proj", }), })); diff --git a/src/tasks/codingAgentTask.ts b/src/tasks/codingAgentTask.ts index b574110..916db58 100644 --- a/src/tasks/codingAgentTask.ts +++ b/src/tasks/codingAgentTask.ts @@ -25,7 +25,7 @@ export const codingAgentTask = schemaTask({ retry: { maxAttempts: 0, }, - run: async (payload) => { + run: async payload => { const { prompt, callbackThreadId } = payload; const { token, teamId, projectId } = getVercelSandboxCredentials(); @@ -63,7 +63,10 @@ export const codingAgentTask = schemaTask({ logStep("Creating PRs via agent"); const timestamp = Date.now(); - const slug = prompt.slice(0, 30).replace(/[^a-zA-Z0-9]/g, "-").toLowerCase(); + const slug = prompt + .slice(0, 30) + .replace(/[^a-zA-Z0-9]/g, "-") + .toLowerCase(); const branch = `agent/${slug}-${timestamp}`; const prs = await pushAndCreatePRsViaAgent(sandbox, { prompt, branch }); diff --git a/src/tasks/customerPromptTask.ts b/src/tasks/customerPromptTask.ts index 3768930..4b3b49f 100644 --- a/src/tasks/customerPromptTask.ts +++ b/src/tasks/customerPromptTask.ts @@ -48,9 +48,7 @@ export const customerPromptTask = schedules.task({ const accountId = taskConfig?.accountId; const artistId = taskConfig?.artistId; const model = taskConfig?.model; - const prompt = - taskConfig?.prompt ?? - "Draft a friendly check-in message for our customers."; + const prompt = taskConfig?.prompt ?? "Draft a friendly check-in message for our customers."; if (!accountId) { logger.error("Missing required accountId from task"); diff --git a/src/tasks/proArtistSocialProfilesScrape.ts b/src/tasks/proArtistSocialProfilesScrape.ts index ddd5358..4f25034 100644 --- a/src/tasks/proArtistSocialProfilesScrape.ts +++ b/src/tasks/proArtistSocialProfilesScrape.ts @@ -36,11 +36,9 @@ export const proArtistSocialProfilesScrape = schedules.task({ // Log artists missing socials for visibility artistIds .filter( - (artistId) => - !artistSocialsMap.get(artistId) || - artistSocialsMap.get(artistId)?.length === 0 + artistId => !artistSocialsMap.get(artistId) || artistSocialsMap.get(artistId)?.length === 0, ) - .forEach((artistId) => { + .forEach(artistId => { logger.warn("No socials found for artist", { artistId }); }); @@ -62,15 +60,15 @@ export const proArtistSocialProfilesScrape = schedules.task({ logger.log("All scrape batches completed", { totalRuns: allResults.length, totalArtists: artistIds.length, - succeeded: allResults.filter((r) => r.status === "SUCCEEDED").length, - failed: allResults.filter((r) => r.status === "FAILED").length, + succeeded: allResults.filter(r => r.status === "SUCCEEDED").length, + failed: allResults.filter(r => r.status === "FAILED").length, }); return { totalArtists: artistIds.length, totalRuns: allResults.length, - succeeded: allResults.filter((r) => r.status === "SUCCEEDED").length, - failed: allResults.filter((r) => r.status === "FAILED").length, + succeeded: allResults.filter(r => r.status === "SUCCEEDED").length, + failed: allResults.filter(r => r.status === "FAILED").length, }; }, }); diff --git a/src/tasks/runSandboxCommandTask.ts b/src/tasks/runSandboxCommandTask.ts index f3aa991..910533a 100644 --- a/src/tasks/runSandboxCommandTask.ts +++ b/src/tasks/runSandboxCommandTask.ts @@ -11,10 +11,7 @@ import { writeReadme } from "../sandboxes/writeReadme"; import { ensureOrgRepos } from "../sandboxes/ensureOrgRepos"; import { ensureSetupSandbox } from "../sandboxes/ensureSetupSandbox"; import { pushSandboxToGithub } from "../sandboxes/pushSandboxToGithub"; -import { - runSandboxCommandPayloadSchema, - type SandboxResult, -} from "../schemas/sandboxSchema"; +import { runSandboxCommandPayloadSchema, type SandboxResult } from "../schemas/sandboxSchema"; /** * Background task that connects to an existing Vercel Sandbox, ensures OpenClaw @@ -85,11 +82,7 @@ export const runSandboxCommandTask = schemaTask({ logStep("Pushing to GitHub"); await pushSandboxToGithub(sandbox); - const snapshotResult = await snapshotAndPersist( - sandbox, - accountId, - githubRepo ?? undefined - ); + const snapshotResult = await snapshotAndPersist(sandbox, accountId, githubRepo ?? undefined); const result: SandboxResult = { stdout, diff --git a/src/tasks/sendPulsesTask.ts b/src/tasks/sendPulsesTask.ts index 7704065..1bd7e29 100644 --- a/src/tasks/sendPulsesTask.ts +++ b/src/tasks/sendPulsesTask.ts @@ -111,7 +111,7 @@ Use send_email with the html parameter to deliver.`; export const sendPulsesTask = schedules.task({ id: "send-pulses-task", cron: { pattern: "0 9 * * *", timezone: "America/New_York" }, // Run daily at 9 AM ET - run: async (payload) => { + run: async payload => { logger.log("Starting send pulses task", { timestamp: payload.timestamp, timezone: payload.timezone, @@ -134,7 +134,7 @@ export const sendPulsesTask = schedules.task({ } logger.log("Processing active pulses", { count: activePulses.length }); - accountIds = activePulses.map((pulse) => pulse.account_id); + accountIds = activePulses.map(pulse => pulse.account_id); } let sent = 0; diff --git a/src/tasks/setupSandboxTask.ts b/src/tasks/setupSandboxTask.ts index 71e0d65..63a8aee 100644 --- a/src/tasks/setupSandboxTask.ts +++ b/src/tasks/setupSandboxTask.ts @@ -17,7 +17,7 @@ export const setupSandboxTask = schemaTask({ retry: { maxAttempts: 0, // Zero retries — run once only }, - run: async (payload) => { + run: async payload => { const { accountId } = payload; logStep("Starting sandbox setup", true, { accountId }); @@ -30,11 +30,7 @@ export const setupSandboxTask = schemaTask({ logStep("Provisioning complete", false); logStep("Taking snapshot"); - const snapshotResult = await snapshotAndPersist( - sandbox, - accountId, - githubRepo, - ); + const snapshotResult = await snapshotAndPersist(sandbox, accountId, githubRepo); logStep("Sandbox setup complete", true, { sandboxId: sandbox.sandboxId, diff --git a/src/tasks/updatePRTask.ts b/src/tasks/updatePRTask.ts index c61604e..3c02730 100644 --- a/src/tasks/updatePRTask.ts +++ b/src/tasks/updatePRTask.ts @@ -23,7 +23,7 @@ export const updatePRTask = schemaTask({ retry: { maxAttempts: 0, }, - run: async (payload) => { + run: async payload => { const { feedback, snapshotId, branch, repo, callbackThreadId } = payload; const { token, teamId, projectId } = getVercelSandboxCredentials();