agentleFS
mcowgermcowger/plexus/.agents/skills/add-quota-checker/SKILL.md

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
  1. Distinctive:

    Every item in this checklist is required.

    line 8
  2. Very specific:

    Add a {Name}QuotaCheckerOptionsSchema const with the checker's options.

    line 43
  3. Very specific:

    Add a z.object({ type: z.literal('my-checker'), ...

    line 44
  4. Very specific:

    Add the type string to quotaCheckerTypeEnum.

    line 48
  5. Distinctive:

    After your PR merges, CI auto-generates the migration.

    line 50
  6. Very specific:

    Do not add an apiKey field — it is auto-inherited from the provider config.

    line 58
  7. Very specific:

    Call onChange whenever any option changes.

    line 59
  8. Distinctive:

    Import the config component at the top.

    line 68
  9. Very specific:

    Add an entry to QUOTA_CONFIG_MAP mapping the lowercase type string to the component.

    line 69
  10. Very specific:

    If the checker has required options, add validation logic to validateQuotaChecker().

    line 75
  11. Distinctive:

    No fallback lists to update — the frontend fetches all known types from the backend at runtime.

    line 77

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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}QuotaCheckerOptionsSchema const with the checker's options.
  • Add a z.object({ type: z.literal('my-checker'), ... }) entry to ProviderQuotaCheckerSchema (the z.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 apiKey field — it is auto-inherited from the provider config.
  • Call onChange whenever any option changes.

index.ts

  • Export the config component.

Frontend — ProviderQuotaEditor (packages/frontend/src/components/providers/ProviderQuotaEditor.tsx)

  1. Import the config component at the top.
  2. Add an entry to QUOTA_CONFIG_MAP mapping 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 in checker-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-types endpoint won't return it.
  • Missing Postgres enum: SQLite ignores enum enforcement; Postgres deployments will reject inserts.
  • Missing QUOTA_CONFIG_MAP entry in ProviderQuotaEditor: The provider edit modal will show the dropdown type but no config form for the checker's options.
  • Missing ProviderQuotaCheckerSchema entry in config.ts: The backend Zod validation will reject configs using the new type.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.