-
.agents/AGENTS.mdand.agents/rules/*.mdcare source of truth. After editing them, runbun installto sync. Never editSKILL.mddirectly. -
In all interactions and commit messages, be extremely concise and sacrifice grammar for the sake of concision.
-
If you get
failed to load config from /Users/zbeyens/GitHub/kitcn/vitest.config.mts, rimraf**/node_modulesand install again. -
Run
convex:logsto watch the Convex logs
-
Git: Never git add, commit, push, or create PR unless the user explicitly asks, or the active command/skill explicitly requires it.
-
Push scope: When you do commit and push, include unrelated dirty files outside src; those are often manual user changes or synced skill/docs updates, so do not silently leave them behind.
-
PR: Before creating or updating a PR, run
check. If it fails, stop and fix it or report the blocker. Do not open a PR with failingcheckunless the user explicitly says to. -
PR branch: If the user explicitly says to open or create a PR, do not ask for confirmation. If the current branch is
main, create a newcodex/branch first, then commit/push/open the PR. If already on a non-mainbranch, proceed directly. -
Dirty workspace: Never pause to ask about unrelated local changes. Continue work and ignore unrelated diffs.
-
Never browse GitHub files. For library/API questions or unfamiliar deps, inspect the repo at
..; if missing, clonehttps://github.com/{owner}/{repo}.gitto../{repo-name}. -
For repo research, use
spawn_agent(... agent_type="explorer")and return file-backed findings from docs, structure, exports, examples, and tests only. -
When using git worktree, copy
example/.env.localandexample/convex/.envto the worktree directory.
- Project is in closed alpha with no external users. Breaking changes are allowed and recommended if they produce better results. No backward compatibility needed. Still confirm with the user before proceeding with a set of breaking changes.
- Breaking changes: default to a hard cut. Do not add backward-compat aliases, deprecated shims, fallback parsing, migration bridges, or tests for the previous API unless the user explicitly asks. Remove the old surface and write tests only for the current behavior, as if the old API never existed.
- Hard cut by default. For feature removal or unshipping, use
hard-cutand delete the feature completely: no deprecation notices, noNot implementedthrows, no compatibility stubs, no dead tests, no comments about deleted code. The user must explicitly ask for the softer path. - Bundle size: Convex does not support dynamic imports. Each function entry bundles everything it statically imports. Prefer splittable per-module patterns (e.g. per-module callers, plugins) over monolithic globals. Keep each entry's import graph minimal.
- Parity: Don't reinvent the wheel. Before designing APIs or architecture, study how proven OSS projects solve the same problem — Drizzle (schema/ORM), tRPC (procedures/middleware), shadcn (CLI/codegen), better-auth (plugin system/auth). Adopt their patterns when applicable. Do
lsin..directory to find the respective repositories, then inspect their source code when needed. - DX: Optimize for the absolute best developer experience. CLI must be first-class for agents — deterministic, machine-readable output (--json), non-interactive defaults (--yes), composable commands. Every API surface should be intuitive for both humans and AI agents.
- Docs (www/): NEVER write changelog-style language ("has been removed", "new feature", "previously", "now supports"). Docs are user-facing reference for the LATEST state only. Write as if no prior version exists. No migration notes, no "what changed" — just document what IS. Follow docs/solutions/style.md for writing tone/structure.
- Docs sync: When updating www/ docs, also update the corresponding content in packages/kitcn/skills/convex/SKILL.md or packages/kitcn/skills/convex/references/ to stay synced. Follow packages/kitcn/skills/convex/references/setup/doc-guidelines.md for compression/placement rules.
- Plugins: ALWAYS read packages/kitcn/skills/convex/references/features/create-plugins.md before creating or modifying plugins. Keep it synced when any plugin API changes in the package.
- Intent maintainer loop: use
bunx intent scaffoldwhen you need new skills or a major skill reshuffle; for normal work, update docs andpackages/kitcn/skills/convex/**in the same diff; runbunx intent validate skillsandbunx intent stale; keep@tanstack/intent,bin/intent.js,bin.intent, and packagefileswired; verify withnpm pack --json --dry-run ./packages/kitcn; after release, treatintent feedbackas product input — tighten the skill if wording is wrong, fix the API if the same workaround keeps repeating. - Always use @.agents/rules/changeset.mdc when updating packages to write a changeset before completing
- After any package modification, run
bun --cwd packages/kitcn build - Use tdd skill for package updates that add or change live behavior.
- Do not write TDD cases for dead code/legacy removal assertions (for example: "should not contain old API X anymore"). Remove the dead path directly and keep tests focused on current behavior.
- Never edit scaffolded example output first. Change package scaffold source, then regenerate scaffold files via CLI.
- Never update example plugin files directly. Update the package plugin template first, then regenerate with
kitcn add ... --overwrite. - When changing
kitcn init -tscaffold output, treatfixtures/**as generated fixture output frombun run fixtures:sync— including committed fixturepackage.jsonfiles. Do not patch fixture files by hand. - After any
init -ttemplate or scaffold change, you must rerunbun run fixtures:syncandbun run fixtures:check. No exceptions. - For manual runtime, never run committed
fixtures/**in place. Materialize a tmp app withbun run scenario:prepare <name>and run it fromtmp/scenarios/<name>/project, or usebun run scenario:dev <name>. - Use @.agents/rules/scenarios.mdc for fixture and scenario runtime proof. It owns when to stop at
scenario:dev, when to addtest:authortest:e2e, and whenscenario:checkis the only honest lane. - Default
bun checkmust not depend on auth browser E2E. Treattest:e2eas an auth-specific lane only. Run it when the diff touches auth runtime/client/provider/query-invalidation surfaces or auth demo scaffolds. - If
bun run fixtures:syncdies with Convex/esbuildEPIPE,The service was stopped, orTimed out waiting for local Convex bootstrap, kill stale workers first:pkill -f 'convex/bin/main.js codegen' || true; pkill -f 'convex/bin/main.js dev' || true; pkill -f '@esbuild/.*/bin/esbuild --service' || true, then rerun sync once. Ifpsstill shows an esbuild worker stuck inUstate afterkill -9, stop bullshitting and reboot — that machine state is wedged. - After every template/scaffold change, verify with
bun run fixtures:sync,bun run fixtures:check, and prepared scenario apps undertmp/scenarios/**. Do not touchexample/unless the user explicitly asks. - Prefer inline Zod schemas when used once; extract constants only when reused.
Use those skills when relevant:
taskfor normal repo task executionmajor-taskfor heavyweight architecture, framework comparison, migration, benchmark, or proposal workdeslopfor the final bounded cleanup pass once a change already workstddce-reviewwhen doing a code review
Convex-specific CE exclusions:
- Do not install or reference these by default in this repo unless the user explicitly asks:
data-integrity-guardian,data-migration-expert,data-migrations-reviewer,schema-drift-detector,deployment-verification-agent,dhh-rails-reviewer,kieran-rails-reviewer,kieran-python-reviewer,previous-comments-reviewer,pr-comment-resolver,figma-design-sync. - Reason: better-convex is a framework/tooling repo. Data migration, Rails, deployment, PR-thread, and Figma workflow agents are mostly overkill or the wrong shape here.
When using the following skills, override the default behavior.
planning-with-files:
- Do not create
task_plan.md,findings.md, orprogress.mdat repo root. Merge that content into one file underdocs/plans/. Example:docs/plans/2026-02-07-fix-schema.md
dev-browser:
- Use
dev-browser --connect http://127.0.0.1:9222by default for browser work. Do not preflight9222first. - Only inspect
9222or usebrowser-debug-setupafter a directdev-browser --connect http://127.0.0.1:9222attempt fails. - Reuse one persistent debug Chrome on
127.0.0.1:9222. Do not spin up disposable browser instances unless the user asks. - Use a dedicated Chrome
--user-data-dirfor that debug browser, not the user's normal daily Chrome data dir. - Clone the signed-in Chrome profile into the dedicated debug dir, then launch the debug browser from that clone.
- On macOS, launch the debug browser with
open -na "Google Chrome" --args ... --remote-debugging-port=9222so it opens as a separate Chrome instance without hijacking the user's normal window. - Do not close or stop the user's connected debug browser. Leave that debug window open and reuse it. Close named pages only when needed.
- Keep scripts small and direct. Prefer
browser.getPage("persistent-main")for the main app. - Use
dev-browserinstead ofagent-browseror next-devtoolsbrowser_eval. - If
dev-browsergets blocked by a human prompt or loops on the same step, stop and ask the user to unblock. After the unblock works:- [Add browser learning]
ce-*:
- plan: Include
dev-browserin acceptance criteria for browser features - deepen-plan: Context7 only when not covered by skills
- work: UI tasks require
dev-browserBEFORE marking complete. Never guess.
🚨 STOP - SKILL ANALYSIS IS MANDATORY
Instructions:
• DO NOT edit until skill analysis is complete.
• Use update_plan only if that tool is available in the current runtime.
• If update_plan is unavailable, run the same checklist inline.
• Condition NO -> mark completed -> proceed
• Condition YES -> work through steps -> mark completed -> proceed
• Skipping skill analysis = FAILED to follow instructions
Skill Analysis Checklist: ☐ Skill analysis (SKIP if 'quick' in message): (1) STOP rationalizing ('simple question', 'overkill', 'might be relevant') (2) List ALL available skills (3) For EACH: 'always apply' or 'Does task involve [topic]?' -> YES/MIGHT/MAYBE = ✓. Only ✗ if DEFINITELY not related (4) Load all ✓ skills in one pass; do NOT load one then wait (5) Output '[Skills: X available, Y loaded: name1, name2]' CRITICAL: 'Might be relevant' = MUST load. '1% chance' = MUST load.
Default Skill Gates:
- Before non-trivial bug/feature work on existing code, load
learnings-researcherand checkdocs/solutionsfirst. - For multi-step work, anything likely to be compacted / use a full context window, or any task that starts trivial but grows into that shape, start/update
planning-with-filesimmediately. Do not wait for compaction or the next turn. - For bug fixes or behavior changes with a sane test seam, use
tddbefore the fix.
🔒 VERIFICATION REQUIRED - NO COMPLETION WITHOUT FRESH EVIDENCE
Instructions:
• Track ALL verification items below (use update_plan if available, otherwise inline)
• Condition NO -> mark completed and skip
• Condition YES -> in_progress -> verify -> completed
• Avoid unnecessary build check
• No final "done", "fixed", or "works" message without fresh same-turn evidence for every required item below, or an explicit blocker.
Verification Checklist:
- Typecheck (IF updated .ts files): Run
typecheck - Lint: Run
lint:fix - PR gate (IF creating/updating a PR): Run
check - Browser verification (IF a browser surface changed): verify with
dev-browser --connect http://127.0.0.1:9222before done - ce-compound (SKIP if trivial): CRITICAL: After completing this request, you MUST evaluate whether it produced extractable knowledge. EVALUATION PROTOCOL (NON-NEGOTIABLE): (1) COMPLETE the user's request first (2) EVALUATE - Did this require non-obvious investigation or debugging? Was the solution something that would help in future similar situations? Did I discover something not immediately obvious from documentation? (3) IF YES to any: load
ce-compoundafter the fix is verified and follow its workflow to capture the solution indocs/solutions/(4) IF NO to all: Skip - no extraction needed This is NOT optional. Failing to evaluate = valuable knowledge lost.
🚨 CONTEXT WIPED - MANDATORY SKILL RELOAD
Instructions:
• STOP. Context compaction DELETED all skills. You FORGOT everything.
• DO NOT proceed until skill reload complete
• DO NOT assume you remember skills - they are GONE
• If planning-with-files should already have been active, load it immediately during recovery before continuing.
• Skipping = GUARANTEED FAILURE
Skill Reload Checklist:
☐ Skill reload (MANDATORY): (1) Check current task tracking (update_plan if available, otherwise inline) (2) List ALL available skills (3) For EACH: 'always apply' or 'Does task involve [topic]?' -> YES/MIGHT/MAYBE = ✓ (4) Load all ✓ skills in one pass; do NOT load one then wait (5) If the task is already multi-step, near compaction, or obviously should have had a file plan, load planning-with-files now before resuming (6) ONLY after reload, resume task CRITICAL: ALL skills GONE. MUST reload. 'Might apply' = MUST load.
When writing code in a project with Ultracite, follow these standards. For the full rules reference, see references/code-standards.md.
Key rules at a glance:
Formatting: 2-space indent, semicolons, double quotes, 80-char width, ES5 trailing commas, LF line endings.
Style: Arrow functions preferred. const by default, never var. for...of over .forEach(). Template literals over concatenation. No enums (use objects with as const). No nested ternaries. Kebab-case filenames.
Correctness: No unused imports/variables. No any (use unknown). Always await promises in async functions. No console.log/debugger/alert in production.
React: Function components only. Hooks at top level. Exhaustive deps. key on iterables (no array index). No nested component definitions. Semantic HTML + ARIA.
Performance: No accumulating spread in loops. No barrel files. No namespace imports. Top-level regex.
Security: rel="noopener" on target="_blank". No dangerouslySetInnerHTML. No eval().