agentleFS
joncoroneljoncoronel/skillbundle/AGENTS.md

skillbundle

AGENTS.md3 starsChanged 42 days agoMITView on GitHub

This file is the primary guidance for AI coding agents (Claude Code, Codex, etc.) working in this repository. It is the single source of truth — CLAUDE.md just imports this file. SkillBundle is a web app for finding AI coding assistant skills and keeping track of the ones you use. It syncs the skills.sh catalog, adds search, filters, comparison, and GitHub repo matching on top, and lets users save skills into shareable bundles and follow changes to them. See PRODUCT.md…

  • Reads credentials
  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository4 other files it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

7 rules. About 0 are common, 1 is distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Check it for planned work and deferred decisions, and add to it rather than letting ideas get lost in chat.

    line 14
  2. Very specific:

    pnpm build needs a reachable Convex deployment: Every generateStaticParams calls fetchQuery (via lib/representative-params.ts), and …

    line 31
  3. Very specific:

    Keep the page component synchronous and pass the params promise down.

    line 101
  4. Very specific:

    Categories are implemented: Every skill gets tags from a fixed list of 28 categories (Frontend, UI & Design, Testing & QA, …), assigned by …

    line 179
  5. Very specific:

    Class names: Use cn() from lib/utils.ts (clsx + tailwind-merge)

    line 199
  6. Very specific:

    Component variants: Use class-variance-authority (cva)

    line 200
  7. Very specific:

    Convex functions: Use v validator from convex/values for all argument/return validation

    line 202

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md 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
AGENTS.md

AGENTS.md

This file is the primary guidance for AI coding agents (Claude Code, Codex, etc.) working in this repository. It is the single source of truth — CLAUDE.md just imports this file.

Project Overview

SkillBundle is a web app for finding AI coding assistant skills and keeping track of the ones you use. It syncs the skills.sh catalog, adds search, filters, comparison, and GitHub repo matching on top, and lets users save skills into shareable bundles and follow changes to them. See PRODUCT.md for the product context, positioning, and pricing rules, and docs/architecture.md for the routes.

Roadmap & ideas

Things we want to build, ideas, and parked decisions live in TODO.md. Check it for planned work and deferred decisions, and add to it rather than letting ideas get lost in chat.

Commands

  • pnpm dev — Start Next.js dev server
  • pnpm build — Production build
  • pnpm lint — Run ESLint
  • pnpm test — Unit tests (vitest, tests/**/*.test.ts — Convex backend logic)
  • pnpm e2e / pnpm e2e:ui — Playwright (e2e/**/*.spec.ts): instant-navigation, landmark, share-metadata, floating-bar-clearance and skill-page guards signed out, plus signed-in functional coverage in e2e/authenticated/
  • npx convex dev — Start Convex dev server (runs alongside Next.js dev)
  • npx convex deploy — Deploy Convex functions to production

Both pnpm dev and npx convex dev must be running during local development.

pnpm build needs a reachable Convex deployment. Every generateStaticParams calls fetchQuery (via lib/representative-params.ts), and prerendering those paths runs the 'use cache' loaders. A fresh clone without .env.local cannot build. The hardcoded fallbacks in representative-params.ts harden param selection, not the render.

Markdown-only pushes do not deploy. vercel.json runs scripts/vercel-ignore-build.mjs, which skips the Vercel build when every file changed since the last successful deploy is *.md. Each deploy resets the ISR cache, so this saves real money. If the app ever reads a .md file at build or run time, narrow that script's match first, or edits to that file will never ship.

Two test suites, deliberately non-overlapping. pnpm test is vitest over tests/**/*.test.ts; pnpm e2e is Playwright over e2e/**/*.spec.ts, against a production build on port 3100. Don't put one kind of test in the other's directory — the globs are what keep the runners apart. pnpm check is format:check + lint + typecheck + unit tests; e2e is separate because it builds the app.

Formatting is gated, so run pnpm format before committing. Prettier owns every file except components/ui/cubby-ui/, which is vendored through shadcn add and excluded in .prettierignore — formatting it would be reverted by the next component update and break the gate on arrival. components/charts/ used to be excluded for the same reason; it is now our own code (see Charts below) and is formatted like everything else.

shadcn add @cubby-ui/style needs a manual pass over app/globals.css afterwards, every time. app/globals.css is NOT in .prettierignore, so the installer's four-space output fails format:check — run pnpm format. It also runs an update-theme pass that echoes every non-color variable back into @theme inline as --x: var(--x). Those are inert (a self-reference is a cycle, and the real values live in the unlayered :root / .dark further down, which outrank the theme layer either way) but they accumulate; delete them. Delete ONLY exact self-references — --color-x: var(--x) entries are real aliases that generate utilities, and --color-chrome: var(--chrome) in particular is what makes bg-chrome work.

.gitattributes pins the working tree to LF and is load-bearing for that gate, not housekeeping. core.autocrlf=true is the Windows default and rewrites files as CRLF whenever git materialises them; Prettier's default endOfLine: "lf" then rejects them. Which files are hit depends on which ones git last checked out, so without the pin pnpm check passes or fails according to your recent branch switches. If format:check ever fails on a file that looks correct, check its line endings first.

Tech Stack

  • Framework: Next.js 16 (App Router) with React 19
  • Backend: Convex (database, serverless functions, cron jobs)
  • Auth: Clerk (JWT-based, synced to Convex via webhooks)
  • Styling: Tailwind CSS v4 with OKLch color system
  • Package manager: pnpm
  • UI components: Custom library in components/ui/cubby-ui/ built on Radix UI and Base UI primitives. Component docs available at https://www.cubby-ui.dev/llms.txt
  • Icons: HugeIcons (primary) and Lucide React
  • Animations: Motion library (motion) for UI; charts animate through TanStack Charts' own motion renderer (see Charts below)
  • Charts: TanStack Charts (@tanstack/charts)

Architecture

This is a high-level map. The detailed, authoritative guides are:

  • docs/architecture.md — frontend & platform: Next.js 16 static-first rendering + caching, the route inventory (static / ISR / dynamic), the Suspense-default-state pattern, Clerk auth wiring, the provider tree, data-fetching patterns, nuqs URL state, and Polar billing. Read this before any frontend / rendering / caching / auth work. Two rules from that guide that are easy to break without noticing, because direct page loads keep working either way:
  • Catalog pages (/[org], /[org]/[repo], /site/[source]) must not await params above their <Suspense> boundaries. Doing so empties the route's shared App Shell and makes every client navigation into it blocking. Keep the page component synchronous and pass the params promise down.
  • Error handling has three layers (app/global-error.tsx, app/(main)/error.tsx, components/data-error-boundary.tsx). Use the innermost one that fits rather than adding try/catch inside a Server Component — that swallows the error and loses retry().
  • Restructuring a page means updating its loading.tsx / Suspense fallback in the same change. Nothing catches that drift — the e2e guards assert a shell commits instantly, not that it resembles the page — and a stale fallback reads to users as the skeleton being replaced by a second, different skeleton rather than as a bug. See docs/architecture.md §2.
  • A section that's expensive on the client usually belongs on the server, not behind a deferral. Deferring keeps the cost and adds a loading phase. Only genuinely per-interaction work (e.g. the shiki diff in components/skill-history-row.tsx) should stay lazy.

e2e/instant-navigation.spec.ts guards the first one. See docs/architecture.md §1, §14 and §15.

  • docs/skill-lifecycle.md — backend skill pipeline: how skills enter the catalog, the sync / reconcile / curated / duplicate-detection jobs, "seen" + delisting rules, snapshots, and the needs* work-set patterns. Read this before touching the sync or skill-lifecycle code.
  • docs/charts.md — the three charts and the TanStack Charts integration: how a definition is composed, what the hover overlay owns versus the library, the motion and density rules, and a long list of traps with the measurements behind them. Read this before touching any chart.

Frontend → backend

ClerkProvider wraps ConvexProviderWithClerk in the root layout (app/layout.tsx). Static-first: route shells prerender (CDN), and per-user/interactive data arrives over the authenticated Convex websocket via useQuery/useMutation (or useQuery(convexQuery(...)) through TanStack Query). Auth is Clerk, bridged to Convex by JWT; the proxy.ts middleware uses an inverted private-route list (/settings, /dev; /dashboard is public because signed-out visitors keep bundles in the browser, see docs/architecture.md §9) because the catch-all org routes shadow everything — see docs/architecture.md §3.

Convex backend (convex/) at a glance

Tables (schema.ts), grouped by concern:

  • Skills catalog: skills (full ~10 KB rows), skillSummaries (slim ~1.3 KB denormalized rows that lists/search/cards read), skillEmbeddings (vector search), skillAudits + skillSnapshots (security verdicts + install-count history), syncStats.
  • Sync / dedup support: curatedOwnerSummaries, githubTreeCache, githubRepoResolution, repoFingerprintCache, wellKnownIndexes (per-domain skills-index probe results; what decides whether a site page can show an install command).
  • Version archive: skillVersions (one row per detected SKILL.md change, raw file in _storage; isBaseline marks a starting point rather than an edit).
  • Users & bundles: users, bundles, repoMatchQuota (free-plan repo-match usage, one row per account). (bundleStats and bundleStars were removed — see the note at the end of schema.ts.)

Modules, grouped by concern:

  • Skill sync & lifecycle: skills.ts (sync pipeline + catalog queries), reconcile.ts, curated.ts / curatedRefresh.ts, duplicates.ts, audits.ts, crons.ts, plus lib/* helpers (detailRefresh, skillHealth, source, appDay, pagination, github, skillsApi, embeddings). Documented in docs/skill-lifecycle.md.
  • Leaderboards & discovery: leaderboards.ts (trending/hot), recommendations.ts (repo-fingerprint matching, plus the signed-out analyzeRepoAnonymous the site's server action calls), repoMatchQuota.ts (the free plan's monthly repo-match allowance; who is metered how is repoMatchMeter in lib/repo-match.ts), tags.ts (category tagging with TypeSafe's Jev model; the category list is lib/categories.ts, what each category means to the model is lib/categoryDefinitions.ts).
  • Well-known sources: wellKnown.ts (weekly probe of each well-known domain's skills index, at the root and under a fixed set of base paths). Read its header before touching any npx skills add string — the command for a well-known source is not derivable from the source, and the obvious form is one the CLI resolves to a GitHub repo.
  • Version archive & monitoring: skillVersions.ts (read + write API over the change archive; freshness.ts decides which SKILL.mds to re-check).
  • Bundles & social: bundles.ts.
  • Users, auth & billing: users.ts, http.ts (Clerk + Polar webhooks, Svix-validated), auth.config.ts, subscriptions.ts / plans.ts / polar.ts, rateLimits.ts (per-user limits on public actions that spend money or GitHub budget; read its header before changing a number or adding an app-wide limit) (+ convex.config.ts registers the @convex-dev/polar and @convex-dev/rate-limiter components).
  • Admin / dev: devStats.ts (the /dev dashboard stats), devSeed.ts, githubOnly.ts (admin add of skills that exist only on GitHub, not on skills.sh — see docs/skill-lifecycle.md "GitHub-only skills"), githubOnlyAudit.ts (read-only diagnostic: GitHub-only rows whose stored slug disagrees with their SKILL.md's frontmatter name), bindAudit.ts (read-only diagnostic: is the RIGHT SKILL.md bound to each skill — a different question from githubOnlyAudit.ts), devSeedFeed.ts (dev-only seeding for the dashboard's change feed).

This list is "at a glance", not exhaustive — but every module and table it NAMES should exist. It has twice pointed at files that had been deleted.

Crons (crons.ts)

Daily sync chain (syncSkills 06:00 UTC → curated 06:30 → snapshot prune 06:45 → reconcileUnseenSkills 07:00, with the discovery/content/audit/embedding pipeline chained off the sync), hourly + 30-min leaderboard refreshes (trending / hot), daily cache cleanups, and a weekly Sunday chain (resolve repo identities 08:00 → curated refresh 09:00 → re-resolve stale identities 10:00 → well-known index probe 11:00). Production-only (gated by CRONS_ENABLED).

Charts

Three charts, all built on TanStack Charts (@tanstack/charts): the sidebar sparkline, the Stats tab's install-history chart, and the compare page's multi-line chart. Shared pieces live in components/charts/; each chart file owns its own defineChart definition, and components/charts/charts.css holds the styling for nodes the library renders and we never author.

docs/charts.md is the authoritative guide — read it before touching any chart. It is mostly a list of traps, each with the measurement behind it, and the code is written short on the assumption you have read them.

One that costs the most time if you miss it: the library ships its own docs and skills inside the package, at node_modules/@tanstack/charts/docs/ and .../skills/, indexed by llms.txt. Read those rather than relying on memory or a docs mirror. They match the installed version, and this is a young library that moves.

Category and technology tagging

Categories are implemented. Every skill gets tags from a fixed list of 28 categories (Frontend, UI & Design, Testing & QA, …), assigned by TypeSafe's Jev model in convex/tags.ts and documented in docs/skill-lifecycle.md "Category tagging". They drive the home page's Category filter and the Categories block in the skill page sidebar. They are deliberately not shown on catalog rows.

To change what a category means, edit convex/lib/categoryDefinitions.ts. Most fixes are a sharper "doesNotCount" line, because the model reads literally. Try the change on a sample (tags:markAllForTagging '{"limit": 200}') before bumping CATEGORIES_VERSION and re-tagging everything. Category keys are stored on rows and in the search index; labels are display-only.

Technology tags (Next.js, Supabase, …) are not implemented. components/skill-card.tsx still has an optional technologies prop that nothing populates. The planned approach is in TODO.md: code finds technology names in the SKILL.md, and Jev judges which ones the skill is actually about.

Conventions

  • Path alias: @/* maps to project root
  • Class names: Use cn() from lib/utils.ts (clsx + tailwind-merge)
  • Component variants: Use class-variance-authority (cva)
  • UI components config: See components.json for shadcn/ui style ("new-york"), icon library, and path aliases
  • Convex functions: Use v validator from convex/values for all argument/return validation
  • One-shot repairs and backfills (hand-run once via npx convex run, then dead) go in their own convex/<name>Repair.ts, with a DELETE-ON-COMPLETION header naming the commands and the exit condition, and a TODO.md entry that owns the deletion. Not inline in the module they repair. Reason, from Aug 2026: a one-shot documented only in its own header was cloned into a near-duplicate the next day (6e12f16 → dcb61f5) because nothing outside the file recorded that it existed. skills.ts still carries several that pre-date this rule (backfillIsDelistedFalse, backfillLastSeenInApi, backfillNeedsRepoResolution, backfillArchiveBaselines) — don't add another. Their presence is the argument for the rule, not an exception to it: none is called by anything, and what records that each is finished is scattered — a schema comment for two (schema.ts), a migration note for the same two (docs/skill-lifecycle.md), a TODO.md entry plus freshness.ts prose for backfillArchiveBaselines, and nothing at all outside its own file for backfillNeedsRepoResolution. No single place says which are retirable, which is exactly what the rule above fixes.
<!-- BEGIN:nextjs-agent-rules -->

This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->

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.