import { draftLoop } from './draft-loop.ts'
import { pickActiveAnomaly } from './loop-helpers.ts'
import { readLoopConfig } from './loop-storage.ts'
import { listAnomalies } from './list-anomalies.ts'
import runLoop from './run-loop.ts'
import { optionalBoolean, optionalString, requireRecord } from './types.ts'
export type PollAnomaliesInput = {
organization?: string
database?: string
branch?: string
account?: string
secretName?: string
dryRun?: boolean
confirm?: boolean
}
/**
* Scheduled Insights poll. Declared job starts disabled. Draft-only unless
* loopEnabled is saved and confirm is set (scheduled runs pass no confirm, so
* they stay draft unless the saved loop is enabled).
* @example
* import pollAnomalies from 'kody:@kody/planetscale/poll-anomalies'
* await pollAnomalies({ dryRun: true })
*/
export async function pollAnomalies(input: PollAnomaliesInput = {}) {
const stored = await readLoopConfig()
const organization = optionalString(input.organization, 'organization') ?? stored.organization
const database = optionalString(input.database, 'database') ?? stored.database
const branch = optionalString(input.branch, 'branch') ?? stored.branch ?? 'main'
if (!organization || !database) {
return {
ok: false,
message: 'Set organization + database with configure-loop before polling Insights.',
}
}
const anomalies = await listAnomalies({
organization,
database,
branch,
account: optionalString(input.account, 'account') ?? stored.account,
secretName: optionalString(input.secretName, 'secretName'),
})
const anomaly = pickActiveAnomaly(anomalies.items)
if (!anomaly) {
return {
ok: true,
organization,
database,
branch,
activeAnomalies: 0,
message: 'No active Insights anomalies.',
}
}
const draft = await draftLoop({
organization,
database,
branch,
anomaly,
githubOwner: stored.githubOwner,
githubRepo: stored.githubRepo,
repositoryUrl: stored.repositoryUrl,
labels: stored.labels,
account: stored.account,
})
const scheduledLive = stored.loopEnabled === true && input.dryRun !== true
const explicitLive = input.confirm === true && input.dryRun !== true
if (!scheduledLive && !explicitLive) {
return {
ok: true,
dryRun: true,
activeAnomalies: anomalies.items.filter((item) => item.active === true).length,
draft,
next: stored.loopEnabled
? 'Re-run with confirm: true to open the issue and launch the implementer.'
: 'Draft only. Enable the loop with configure-loop ({ loopEnabled: true, confirm: true }).',
}
}
return runLoop({
organization,
database,
branch,
anomalyId: anomaly.id,
confirm: true,
})
}
/**
* Scheduled Insights poll. Declared job starts disabled.
* @example
* import pollAnomalies from 'kody:@kody/planetscale/poll-anomalies'
* await pollAnomalies({ dryRun: true })
*/
export default async function pollAnomaliesEntrypoint(
params: Partial<PollAnomaliesInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'poll-anomalies')
return pollAnomalies({
organization: optionalString(input.organization, 'organization'),
database: optionalString(input.database, 'database'),
branch: optionalString(input.branch, 'branch'),
account: optionalString(input.account, 'account'),
secretName: optionalString(input.secretName, 'secretName'),
dryRun: optionalBoolean(input.dryRun, 'dryRun'),
confirm: optionalBoolean(input.confirm, 'confirm'),
})
}