add-quota-checker
Skill238 starsChanged 10 days agoMITView on GitHub
Step-by-step checklist for adding a new quota checker to Plexus. Use whenever asked to implement a new quota checker type — covers backend registration, frontend components, display integration, and common pitfalls.
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 4 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Every item in this checklist is required.
- Very specific: line 43
Add a {Name}QuotaCheckerOptionsSchema const with the checker's options.
- Very specific: line 44
Add a z.object({ type: z.literal('my-checker'), ...
- Very specific: line 48
Add the type string to quotaCheckerTypeEnum.
- Distinctive: line 50
After your PR merges, CI auto-generates the migration.
- Very specific: line 58
Do not add an apiKey field — it is auto-inherited from the provider config.
- Very specific: line 59
Call onChange whenever any option changes.
- Distinctive: line 68
Import the config component at the top.
- Very specific: line 69
Add an entry to QUOTA_CONFIG_MAP mapping the lowercase type string to the component.
- Very specific: line 75
If the checker has required options, add validation logic to validateQuotaChecker().
- Distinctive: line 77
No fallback lists to update — the frontend fetches all known types from the backend at runtime.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Adding a New Quota Checker
Every item in this checklist is required. The provider edit modal will not show the new checker type if any registration is missed.
Backend
1. Create the checker file (packages/backend/src/services/quota/checkers/{name}-checker.ts)
Implement the checker using defineChecker(). The type and displayName fields on this object are the sole source of truth — they drive the API, the frontend dropdown, and all display labels automatically.
import { defineChecker } from '../checker-registry';
import { z } from 'zod';
export default defineChecker({
type: 'my-checker', // lowercase, kebab-case
displayName: 'My Checker', // human-readable label shown in the UI
optionsSchema: z.object({
apiKey: z.string().min(1, 'API key is required'),
endpoint: z.string().url().optional(),
}),
async check(ctx) {
// ... fetch and return Meter[]
},
});2. Add the import to loadAllCheckers() in packages/backend/src/services/quota/checker-registry.ts
await import('./checkers/my-checker');Note: this manual step exists because Bun does not yet support
import.meta.glob(tracked in oven-sh/bun#21459). When that ships,loadAllCheckers()will auto-discover checkers and this step will be removed.
3. Add the Zod schema to packages/backend/src/config.ts
- Add a
{Name}QuotaCheckerOptionsSchemaconst with the checker's options. - Add a
z.object({ type: z.literal('my-checker'), ... })entry toProviderQuotaCheckerSchema(thez.discriminatedUnion).
4. Postgres enum (packages/backend/drizzle/schema/postgres/enums.ts)
Add the type string to quotaCheckerTypeEnum. SQLite ignores enum enforcement — Postgres deployments will reject inserts without this.
After your PR merges, CI auto-generates the migration. Do not create or edit migration files manually.
Frontend — Config component (packages/frontend/src/components/quota/)
{Name}QuotaConfig.tsx
- Props:
options: Record<string, unknown>,onChange: (options: Record<string, unknown>) => void - Do not add an
apiKeyfield — it is auto-inherited from the provider config. - Call
onChangewhenever any option changes.
index.ts
- Export the config component.
Frontend — ProviderQuotaEditor (packages/frontend/src/components/providers/ProviderQuotaEditor.tsx)
- Import the config component at the top.
- Add an entry to
QUOTA_CONFIG_MAPmapping the lowercase type string to the component.
Frontend — validation (packages/frontend/src/hooks/useProviderForm.tsx)
If the checker has required options, add validation logic to validateQuotaChecker().
No fallback lists to update — the frontend fetches all known types from the backend at runtime.
That's it
The type and displayName you set in defineChecker() are automatically:
- Returned by
GET /v0/management/quota-checker-types - Returned by
GET /v0/management/quota-checkers(knownTypes + configured) - Used in the provider edit modal dropdown
- Used in Quotas page headings, sidebar cards, and all display labels
There are no frontend constant lists to update.
Common Mistakes
- Missing
loadAllCheckers()import inchecker-registry.ts: The checker will never be registered — the registry stays empty for that type, the type won't appear in the dropdown, and the/v0/management/quota-checker-typesendpoint won't return it. - Missing Postgres enum: SQLite ignores enum enforcement; Postgres deployments will reject inserts.
- Missing
QUOTA_CONFIG_MAPentry inProviderQuotaEditor: The provider edit modal will show the dropdown type but no config form for the checker's options. - Missing
ProviderQuotaCheckerSchemaentry inconfig.ts: The backend Zod validation will reject configs using the new type.
In this repository10 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-provider-presetSkill
- agent-browserSkill
- batch-grill-meSkill
- db-schema-migrationsSkill
- frontend-testingSkill
- plexus-cliSkill
- plexus-rest-apiSkill
- to-ticketsSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

