Skip to content
← Community packages

Turn PlanetScale Insights anomalies into GitHub issues, implementer PRs, and a human review ping.

Browse files

  • Integrations
  • planetscale
  • insights
  • anomalies
  • slow-query
  • postgres
  • vitess
  • github
  • cursor
  • webhook
  • dry-run
License
MIT
Published
August 24, 2026
Pinned commit
55a531f
Rating
No ratings yet
Forks
0
Stars
0
Adaptation effort

README

@kody/planetscale

Intent

Reusable PlanetScale Insights helpers so a forked Kody package can turn a slow query into the loop people actually want: open a GitHub issue, launch an implementer that opens a PR, let a reviewer agent look at that PR, then ping a human. Success is a dry-run draft you can inspect, then a confirmed run that does not start from scratch each time.

This listing is meant to be forked. After you fork, save your own planetscaleApiToken, point configure-loop at your org/database/repo, and keep loopEnabled off until you want webhooks or the poll job to create issues. No personal organization ids, database names, or tokens are hard-coded.

Share this package as https://kody.codes/@kody/planetscale (never a /community/{listing_id} URL).

The loop

  1. PlanetScale Insights reports an anomaly (branch.anomaly webhook or a poll).
  2. draft-loop writes the GitHub issue body, implementer prompt, reviewer prompt, and human ping.
  3. run-loop (after confirm: true) opens the issue, launches a Cursor Cloud implementer with autoCreatePR, and asks Cursor to request a reviewer.
  4. The human gets an email ping (and @kody/notify if that fork is configured).
  5. Repeat when Insights flags the next slow query.

run-loop remembers the last processed anomaly id in packageStorage(), so the same signal does not open a new issue every poll.

Auth

PlanetScale service tokens are sent as Authorization: SERVICE_TOKEN_ID:SERVICE_TOKEN with no scheme. Save that exact id:token value in Kody.

  1. Create a token in the PlanetScale dashboard with at least read_organization, read_database, and Insights read. Add write_database only if you will create the branch.anomaly webhook from this package.
  2. Save it in Kody (do not paste the value in chat):
https://kody.codes/account/secrets/new?name=planetscaleApiToken&description=PlanetScale%20service%20token%20as%20SERVICE_TOKEN_ID%3ASERVICE_TOKEN%20for%20api.planetscale.com&allowedHosts=api.planetscale.com&scope=user
  1. Approve host api.planetscale.com.
  2. Optional webhook HMAC secret (header X-PlanetScale-Signature, SHA-256 hex):
https://kody.codes/account/secrets/new?name=planetscaleWebhookSecret&description=PlanetScale%20webhook%20HMAC%20secret%20(X-PlanetScale-Signature)&allowedHosts=api.planetscale.com&scope=user

Pass account: "work" to use secret planetscaleApiToken-work, or pass secretName: "planetscaleApiToken-work". There are no hard-coded account aliases.

Hosts

  • api.planetscale.com — all REST calls (required)

GitHub, Cursor, and notify

Live loop steps call official helpers:

  • kody:@kody/github/requestPOST /repos/{owner}/{repo}/issues
  • kody:@kody/cursor/agentscreateAgent with autoCreatePR: true and a reviewer request
  • kody.email_send — ping the signed-in Kody user
  • kody:@kody/notify — extra fanout after you fork notify and save your channels

createAgent has no dry-run. This package never calls it unless confirm: true. Connect GitHub OAuth (https://kody.codes/connect/oauth?provider=github) and save a Cursor API key before a live run. @kody/notify platform storage is not your inbox — fork notify first if you want Slack/Discord/Telegram.

The implementer prompt tells the Cursor agent to open the PR itself with ManagePullRequest. Kody does not open that PR as a substitute.

Mutation safety

configure-loop defaults to { dryRun: true, wouldSave } and writes packageStorage() only with confirm: true.

run-loop defaults to a preview { dryRun: true, draft, wouldCall }. Live GitHub issues, Cursor agents, and pings require confirm: true.

create-webhook and mutating request calls throw unless confirm: true. Pass dryRun: true to preview.

The declared poll-anomalies job starts disabled. The insights webhook stays draft-only until configure-loop saves loopEnabled: true.

import runLoop from 'kody:@kody/planetscale/run-loop'

const preview = await runLoop({
	organization: 'acme',
	database: 'app',
	branch: 'main',
	githubOwner: 'acme',
	githubRepo: 'app',
	dryRun: true,
})

const live = await runLoop({
	organization: 'acme',
	database: 'app',
	branch: 'main',
	githubOwner: 'acme',
	githubRepo: 'app',
	confirm: true,
})

Smoke test

import smokeTest from 'kody:@kody/planetscale/smoke-test'

export default async function main() {
	return await smokeTest()
}

Without planetscaleApiToken this still returns { ok: true, live: false } plus setup URLs and a fixture loop draft. With credentials it lists organizations and does not return billing emails. It never opens issues or agents.

Quick start after fork

import configureLoop from 'kody:@kody/planetscale/configure-loop'
import runLoop from 'kody:@kody/planetscale/run-loop'

export default async function main() {
	await configureLoop({
		organization: 'acme',
		database: 'app',
		branch: 'main',
		githubOwner: 'acme',
		githubRepo: 'app',
		repositoryUrl: 'https://github.com/acme/app',
		confirm: true,
	})
	return await runLoop({ dryRun: true })
}

To let the insights webhook or an enabled poll create issues:

import configureLoop from 'kody:@kody/planetscale/configure-loop'

export default async function main() {
	return await configureLoop({ loopEnabled: true, confirm: true })
}

Then create a PlanetScale webhook for branch.anomaly that POSTs to this package's insights webhook URL. Preview the PlanetScale side first:

import createWebhook from 'kody:@kody/planetscale/create-webhook'

export default async function main() {
	return await createWebhook({
		organization: 'acme',
		database: 'app',
		url: 'https://YOUR-KODY-INSIGHTS-WEBHOOK',
		dryRun: true,
	})
}

Exports

  • kody:@kody/planetscale — action dispatcher (defaults to overview)
  • kody:@kody/planetscale/accounts — resolve secret name and setup URLs
  • kody:@kody/planetscale/smoke-test — credential-optional smoke test
  • kody:@kody/planetscale/list-organizations — list organizations (read-only)
  • kody:@kody/planetscale/list-databases — list databases (read-only)
  • kody:@kody/planetscale/list-branches — list branches (read-only)
  • kody:@kody/planetscale/list-anomalies — list Insights anomalies (read-only)
  • kody:@kody/planetscale/list-queries — list Insights queries, default sort p99_latency (read-only)
  • kody:@kody/planetscale/draft-loop — format issue + prompts (no writes)
  • kody:@kody/planetscale/configure-loop — save org/db/repo targets (dryRun / confirm)
  • kody:@kody/planetscale/run-loop — preview or run the issue → PR → ping loop
  • kody:@kody/planetscale/handle-webhookbranch.anomaly webhook handler
  • kody:@kody/planetscale/poll-anomalies — scheduled Insights poll (job starts disabled)
  • kody:@kody/planetscale/create-webhook — create a PlanetScale webhook (dryRun / confirm)
  • kody:@kody/planetscale/request — low-level PlanetScale API escape hatch
  • kody:@kody/planetscale/types — shared TypeScript types

Notes

  • REST base: https://api.planetscale.com/v1
  • List helpers return { items, pageInfo }.
  • Insights dashboard URLs look like https://app.planetscale.com/{org}/{db}/{branch}/insights.
  • branch.anomaly webhook bodies include organization, database, and resource.name (the branch). The handler then lists Insights anomalies.
  • This package is not affiliated with or endorsed by PlanetScale.

Branding

community-icon.svg is PlanetScale's official white logomark from planetscale.com/brand (planetscale-logo-mark-white.svg on black #000000). Paths are unmodified except for a square tile so the mark stays legible at 56 pixels. PlanetScale® is a trademark of PlanetScale, Inc. This package is not affiliated with or endorsed by PlanetScale.

Docs

Report this listing

Log in to report this listing.