import type { AutomationBlueprint, CronDeliveryTarget, CronJob, CronJobCreatePayload, CronJobUpdates, SessionInfo } from '@/types/hermes' import { connectionScoped, hermesApi, profileScoped, STARTUP_REQUEST_TIMEOUT_MS } from './client' // The cron trigger endpoint intentionally waits for the whole job so its // response reflects the persisted execution result. Agent jobs can run far // longer than the Electron fetch default; keep this override local to the one // synchronous long-operation endpoint rather than weakening all API timeouts. const CRON_TRIGGER_REQUEST_TIMEOUT_MS = 24 * 60 * 60 * 1000 // Cron jobs are stored per-profile (/cron/jobs.json), and the // backend's list endpoint defaults to 'all'. Pass a concrete profile key to // list just that profile's jobs, or 'all' for the unified cross-profile view. // Omitting the arg keeps the legacy 'all' default for non-profile callers. // profileScoped() still rides along for backend-process routing. export function getCronJobs(profile?: string): Promise { const suffix = profile ? `?profile=${encodeURIComponent(profile)}` : '' return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs${suffix}`, timeoutMs: STARTUP_REQUEST_TIMEOUT_MS }) } export function getCronJob(jobId: string): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}` }) } export async function getCronJobRuns(jobId: string, limit = 20): Promise { const { runs } = await hermesApi<{ runs: SessionInfo[] }>({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}/runs?limit=${limit}` }) return runs ?? [] } // The single source of truth for cron delivery targets (local + configured // gateways). Both the manual cron editor and the blueprint dialog use this so // they never offer a platform that isn't connected. Mirrors the dashboard. export async function getCronDeliveryTargets(): Promise { const { targets } = await hermesApi<{ targets: CronDeliveryTarget[] }>({ ...profileScoped(), ...connectionScoped(), path: '/api/cron/delivery-targets' }) return targets ?? [] } export function createCronJob(body: CronJobCreatePayload): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: '/api/cron/jobs', method: 'POST', body }) } export function updateCronJob(jobId: string, updates: CronJobUpdates): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}`, method: 'PUT', body: { updates } }) } export function pauseCronJob(jobId: string): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}/pause`, method: 'POST' }) } export function resumeCronJob(jobId: string): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}/resume`, method: 'POST' }) } export function triggerCronJob(jobId: string): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}/trigger`, method: 'POST', timeoutMs: CRON_TRIGGER_REQUEST_TIMEOUT_MS }) } export function deleteCronJob(jobId: string): Promise<{ ok: boolean }> { return hermesApi<{ ok: boolean }>({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/jobs/${encodeURIComponent(jobId)}`, method: 'DELETE' }) } // Automation Blueprints — parameterized cron templates the backend serves from // cron/blueprint_catalog.py. getAutomationBlueprints returns the gallery // (deliver options already rewritten to this machine's configured gateways); // instantiateAutomationBlueprint fills the slots and creates a real cron job via // the same create_job path as createCronJob. // // Profile-scoping is intentionally asymmetric: the GET catalog is global (the // list endpoint takes no profile — only deliver options are rewritten from the // configured gateways), so it carries only the profileScoped() header for // routing. instantiate creates a real per-profile job, so it names the target // profile explicitly via ?profile=. This mirrors the dashboard's api.ts. export function getAutomationBlueprints(): Promise<{ blueprints: AutomationBlueprint[] }> { return hermesApi<{ blueprints: AutomationBlueprint[] }>({ ...profileScoped(), ...connectionScoped(), path: '/api/cron/blueprints', timeoutMs: STARTUP_REQUEST_TIMEOUT_MS }) } export function instantiateAutomationBlueprint( body: { blueprint: string; values: Record }, profile: string ): Promise { return hermesApi({ ...profileScoped(), ...connectionScoped(), path: `/api/cron/blueprints/instantiate?profile=${encodeURIComponent(profile)}`, method: 'POST', body }) }