import { accounts } from './accounts.ts'
import { buildLoopDraft } from './draft-loop.ts'
import { listOrganizations } from './list-organizations.ts'
import { apiTokenSetupUrl, insightsUrl, webhookSecretSetupUrl } from './setup.ts'
import type { PlanetscaleAuthInput } from './types.ts'
import { requireRecord } from './types.ts'
function fixtureDraft() {
return buildLoopDraft({
target: {
organization: 'acme',
database: 'app',
branch: 'main',
githubOwner: 'acme',
githubRepo: 'app',
repositoryUrl: 'https://github.com/acme/app',
},
anomaly: {
id: 'anom_smoke',
active: true,
periodStart: '2026-08-24T00:00:00.000Z',
periodEnd: '2026-08-24T01:00:00.000Z',
minutesInViolation: 12,
duration: 720,
correlations: [
{
id: 'corr_smoke',
fingerprint: 'select-users-by-email',
normalizedSql: 'SELECT * FROM users WHERE email = ?',
keyspace: null,
r: 0.92,
},
],
},
})
}
/**
* Credential-optional smoke test. Without a service token this still returns
* setup URLs and a fixture loop draft. With a token it lists organizations
* (no billing emails) and does not open issues or agents.
* @example
* import smokeTest from 'kody:@kody/planetscale/smoke-test'
* const result = await smokeTest()
*/
export async function smokeTest(input: PlanetscaleAuthInput = {}) {
const accountInfo = await accounts(input)
const draft = fixtureDraft()
const setup = {
serviceTokenUrl: apiTokenSetupUrl(accountInfo.secretName),
webhookSecretUrl: webhookSecretSetupUrl(),
secretName: accountInfo.secretName,
apiTokenSaved: accountInfo.apiTokenSaved,
insightsExample: insightsUrl('your-org', 'your-db', 'main'),
communityUrl: 'https://kody.codes/@kody/planetscale',
}
if (!accountInfo.apiTokenSaved) {
return {
ok: true,
live: false,
setup,
draft: {
title: draft.title,
insightsUrl: draft.insightsUrl,
hasImplementerPrompt: draft.implementerPrompt.includes('ManagePullRequest'),
hasReviewerPrompt: draft.reviewerPrompt.includes('fingerprint'),
},
message:
'PlanetScale loop helpers are loaded. Save a service token, then call list-organizations or draft-loop. run-loop stays dry-run until confirm: true.',
}
}
const organizations = await listOrganizations({
account: input.account,
secretName: input.secretName,
perPage: 5,
})
return {
ok: true,
live: true,
setup,
organizations: organizations.items.map((item) => ({
id: item.id,
name: item.name,
})),
draft: {
title: draft.title,
insightsUrl: draft.insightsUrl,
},
message: 'Service token works. No issues or Cursor agents were created.',
}
}
/**
* Credential-optional smoke test.
* @example
* import smokeTest from 'kody:@kody/planetscale/smoke-test'
* await smokeTest()
*/
export default async function smokeTestEntrypoint(
params: PlanetscaleAuthInput & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'smoke-test')
return smokeTest({
account: typeof input.account === 'string' ? input.account : undefined,
secretName: typeof input.secretName === 'string' ? input.secretName : undefined,
})
}