[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-convex-labs-quickstart":3,"mdc--jnuk0i-key":38,"related-org-convex-labs-quickstart":2686,"related-repo-convex-labs-quickstart":2868},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":27,"repoUrl":28,"updatedAt":29,"license":30,"forks":31,"topics":32,"repo":33,"sourceUrl":36,"mdContent":37},"labs-quickstart","scaffold Convex applications with shadcn\u002Fui","LABS — the FULL Convex quickstart experience: scaffold a running Next.js + shadcn app from one sentence with passkey (WebAuthn) sign-in and a live in-app Chef feedback panel pre-baked, build the idea live, then PUBLISH it to a public https:\u002F\u002F\u003Capp>.convex.app URL (with the user's confirmation before publishing). TRIGGER when the user runs $labs-quickstart, or asks for the full\u002Flabs quickstart, a published\u002Fpublic app, sign-in\u002Fpasskeys, or the in-app feedback panel from scratch. For a plain local-only scaffold use $quickstart instead. SKIP when there's already a Convex project in the cwd.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"convex","Convex","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fconvex.png","get-convex",[13,17,18,21,24],{"name":14,"slug":15,"type":16},"Auth","auth","tag",{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},"Next.js","next-js",{"name":22,"slug":23,"type":16},"shadcn\u002Fui","shadcn-ui",{"name":25,"slug":26,"type":16},"Frontend","frontend",2,"https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fconvex-codex-plugin","2026-07-18T05:12:51.422798","Apache-2.0",0,[],{"repoUrl":28,"stars":27,"forks":31,"topics":34,"description":35},[],"Codex plugin for the hosted Convex MCP server","https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fconvex-codex-plugin\u002Ftree\u002FHEAD\u002Fplugins\u002Fconvex\u002Fskills\u002Flabs-quickstart","---\nname: \"labs-quickstart\"\ndescription: \"LABS — the FULL Convex quickstart experience: scaffold a running Next.js + shadcn app from one sentence with passkey (WebAuthn) sign-in and a live in-app Chef feedback panel pre-baked, build the idea live, then PUBLISH it to a public https:\u002F\u002F\u003Capp>.convex.app URL (with the user's confirmation before publishing). TRIGGER when the user runs $labs-quickstart, or asks for the full\u002Flabs quickstart, a published\u002Fpublic app, sign-in\u002Fpasskeys, or the in-app feedback panel from scratch. For a plain local-only scaffold use $quickstart instead. SKIP when there's already a Convex project in the cwd.\"\nlicense: \"Apache-2.0\"\n---\n\n# Convex Labs Quickstart ($labs-quickstart)\n\nThe **full** quickstart experience (labs): a running Next.js + shadcn \"wow-shell\"\nConvex app from one sentence, with **passkey sign-in** and the **Chef feedback\npanel** pre-baked, built live — and, once v1 works and **the user confirms**,\n**published to a public `https:\u002F\u002F\u003Capp>.convex.app` URL**. The heavy scaffold runs\nas a served shell script from the Convex quickstart backend (\"anteater\"); your job\nis to launch it, then build.\n\n> Want just a plain, local-only scaffold (no login, no panel, no publishing)?\n> That's the **`$quickstart`** skill — use it instead.\n\nThe user's request after `$labs-quickstart` is the **app idea** (e.g.\n`$labs-quickstart a movie-night voting app` → idea = \"a movie-night voting app\").\nIf no idea was given, ask for a one-sentence idea, then continue.\n\n## Degradation rule — when the scaffold can't run, write code, not ceremony\n\nIf the bootstrap can't run — a non-interactive\u002Fone-shot session, no network access, a\nsandboxed temp dir, or the user just wants code rather than a running app — **don't\nwait on the scaffold or the panel\u002Fpasskey\u002Fpublish machinery**. Write a standard Convex\nproject directly:\n\n- **ALL backend code goes under `convex\u002F`** (`schema.ts`, queries, mutations, actions)\n  — **NEVER at the project root.** Convex functions only run from the `convex\u002F`\n  directory.\n- **Write ZERO scaffold\u002Fdocumentation files** unless explicitly asked — no\n  `START_HERE.md`, `ARCHITECTURE.md`, `MANIFEST.txt`, or README walls. \"Build me a\n  backend\" is a request for code, not a design-doc package.\n\n## Data access + imports — read before writing any convex\u002F*.ts\n\n- Never an unbounded `.collect()` on a table that can grow — use `.withIndex(...)` +\n  `.paginate(paginationOpts)`\u002F`.take(n)`.\n- Index, don't filter — `.index(...)` in `schema.ts` for every read path, queried via\n  `.withIndex(...)`; `.filter()` is a full table scan.\n- Imports: `query`\u002F`mutation`\u002F`action`\u002F`internalQuery`\u002F`internalMutation`\u002F`internalAction`\n  from `\".\u002F_generated\u002Fserver\"`; `api`\u002F`internal` from `\".\u002F_generated\u002Fapi\"`; never from\n  `\"convex\u002Fserver\"` in application code.\n- `v.literal(\"exact value\")` for fixed string\u002Fenum members, not a bare `v.string()`.\n- `\"use node\";` is action-only — never in a file that also exports a `query` or\n  `mutation`.\n\n## Self-verify — before declaring backend work done\n\nBefore you call any backend work finished: run `npx tsc --noEmit` and, when a\ndeployment is available (or via a local anonymous one:\n`CONVEX_AGENT_MODE=anonymous npx convex dev --once`), push it. Fix every error\neither one reports before finishing — one verify round catches the\nwrong-relative-import \u002F duplicate-symbol \u002F unbalanced-paren class that otherwise\nbreaks the deploy.\n\n## STEP 0 — launch the scaffold NOW (before anything else)\n\nRun this **first**, before any reasoning or other tool calls — it kicks off the\n~45–120s scaffold (npm install, convex dev, next dev) in the background so it's\ninstalling while you read the rest. Substitute the user's idea for `\u003CIDEA>`:\n\n```bash\nBASE=\"https:\u002F\u002Fbasic-anteater-667.convex.site\"\nIDEA=\"\u003CIDEA>\"\nSLUG=$(curl -fsS --max-time 15 -X POST \"$BASE\u002Fgenerate\" -H 'content-type: application\u002Fjson' \\\n  --data \"$(node -e 'process.stdout.write(JSON.stringify({idea:process.argv[1],template:\"nextjs-shadcn\"}))' \"$IDEA\")\" \\\n  | node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(JSON.parse(s).id||\"\")}catch{}})') || true\necho \"SLUG=$SLUG\"\nQB=$(mktemp -t convex-qb-XXXX.sh)\ncurl -fsS --max-time 20 \"$BASE\u002Fquickstart-bootstrap\" -o \"$QB\" || { echo \"BOOTSTRAP_FETCH_FAILED\"; exit 3; }\n# The bootstrap is feature-flagged via a profile. LABS ships the FULL profile:\n# passkey auth pre-baked, the Chef feedback panel wired, and public *.convex.app\n# publishing enabled — EXCEPT custom domains, which stay off (QB_DOMAIN=0).\n# Only fall back from pre-baked passkeys if the idea asked for a different auth\n# method (else the agent rips it out mid-build). Emit AUTH_MODE for STEP 2.\nif printf '%s' \"$IDEA\" | grep -qiE 'oauth|google (sign|login|auth)|github (login|auth)|sso|saml|magic[ -]?link|password[- ]?only|email.?(\\+|and|\u002F).?password|clerk|workos|auth0|\\.tgz'; then echo \"AUTH_MODE=custom\"; else echo \"AUTH_MODE=passkeys\"; fi\n# QB_HARNESS=codex tags telemetry; QB_ARGS_BASE\u002FQB_FEEDBACK_URL keep the args +\n# panel feedback on the same host the slug was generated on.\nnohup env QB_PROFILE=full QB_DOMAIN=0 QB_HARNESS=codex QB_ARGS_BASE=\"$BASE\" QB_FEEDBACK_URL=\"$BASE\u002Ffeedback\" \\\n  bash \"$QB\" $SLUG > .quickstart-bootstrap.log 2>&1 &\necho \"SCAFFOLD_LAUNCHED log=.quickstart-bootstrap.log SLUG=$SLUG\"\n```\n\n- If it prints `SCAFFOLD_LAUNCHED`, the scaffold is running in the background.\n  **Do NOT run it again.** Note the `SLUG=`.\n- If `curl` is blocked or you see `BOOTSTRAP_FETCH_FAILED`, the network\u002Fsandbox\n  blocked it — tell the user they likely need to run Codex with network access \u002F\n  auto-approve (`codex --sandbox danger-full-access`), then retry.\n\n## STEP 1 — wait for the scaffold, open the browser\n\nPoll `.quickstart-bootstrap.log` until it contains `BOOTSTRAP_COMPLETE`.\n\n**Codex's sandbox often reaps backgrounded (`nohup … &`) processes when the launch\ncall returns** — so the bootstrap may write its first line, then die before scaffolding.\nIf within ~20s the log has stalled (no new lines), **no app subdirectory has appeared**,\nand there's no `BOOTSTRAP_COMPLETE`, the background launch was reaped. Recover by running\nthe bootstrap in the **FOREGROUND** — re-run the STEP 0 block but replace the\n`nohup env … &` line with a plain foreground run, same env:\n\n```bash\nQB_PROFILE=full QB_DOMAIN=0 QB_HARNESS=codex QB_ARGS_BASE=\"$BASE\" QB_FEEDBACK_URL=\"$BASE\u002Ffeedback\" bash \"$QB\" $SLUG\n```\n\nIt backgrounds `convex dev` \u002F `next dev` itself and returns at `BOOTSTRAP_COMPLETE` in\n~1–2 min (set a generous command timeout, 300s+). `BOOTSTRAP_FETCH_FAILED` → server\nunreachable; tell the user. When it completes the log prints:\n- `OPEN_BROWSER_URL: http:\u002F\u002Flocalhost:\u003Cport>` — open this for the user immediately.\n- The app is scaffolded in a new subdirectory with `convex dev` + `next dev` running\n  and error watchers armed (`convex-errors.log` \u002F `next-errors.log` paths are in the log).\n\n## STEP 2 — read the runbook + build the idea live\n\nRead the personalized runbook for the full build flow (it's served — fetch it):\n\n```bash\ncurl -fsS \"https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fq\u002F$SLUG.md\"\n```\n\nThen build the user's idea following it. What's already done by the scaffold:\n- **Auth:** check `AUTH_MODE` in the launch log. If `AUTH_MODE=custom` (the idea\n  asked for OAuth\u002Fpassword\u002Fmagic-link\u002Fa specific auth component), passkeys were NOT\n  pre-baked — wire the **requested** provider per its README (delegate `convex\u002F` code\n  to the `convex-expert` skill) and skip the passkey button. If `AUTH_MODE=passkeys`\n  (default), **passkeys** are pre-baked (`@convex-dev\u002Fauth` pinned build,\n  `convex\u002Fauth.ts`, `...authTables`, `ConvexAuthProvider`, JWT keys set) — you add the\n  **email-first sign-in UI**: an email input + one call to\n  `usePasskeyAuth().signInOrRegisterWithPasskey({ email })`, which signs the user in if\n  they already have a passkey for that email or registers a new one (the build enables\n  enumeration-by-email + autofill). Use the returned `registered` flag for the\n  welcome message; give the input `autoComplete=\"username webauthn\"` for autofill.\n  ⚠ The email is self-asserted\u002Funverified — authorize off the Convex user `_id`\n  (`getAuthUserId`), never `user.email`.\n- The **Chef feedback panel** is wired — keep the `FeatureRequestPanel` mount (a\n  floating panel in the layout, e.g. `app\u002F_chef-panel.tsx` \u002F `\u003CChefPanel \u002F>`) — **never\n  delete or unmount it**. **Narrate your build through the panel, not chat** —\n  `npx convex run progress:post '{\"message\":\"…\"}'`,\n  `npx convex run todos:plan '{\"items\":[…]}'` \u002F `todos:advance`, ask the user\n  clarifying questions with `npx convex run refinementQuestions:ask '{\"text\":\"…\"}'`,\n  and resolve incoming feature requests with\n  `npx convex run featureRequests:setState '{\"id\":\"…\",\"state\":\"…\"}'`.\n- **Custom domains are NOT part of this release** — don't brainstorm, offer, or\n  register domains, and don't look for `.quickstart-domains.json`. (If the user\n  already owns a domain and asks to wire it, that's the separate `$domains` skill.)\n\nRules while building:\n- Delegate all code inside `convex\u002F` to the **`convex-expert`** skill's rules\n  (object-form syntax, validators, indexes, internal vs public).\n- Watch for `convex\u002F` + `next` errors and fix them as they appear — the easiest way\n  is the `fix_errors_automatically` tool (see STEP 4), which surfaces them as events.\n\n## STEP 3 — publish to *.convex.app (ASK THE USER FIRST)\n\nWhen the app builds clean and the core feature works (your \"v1\"), **offer to\npublish** — do not publish silently:\n\n> \"v1 is working locally. Want me to publish it to a public\n>  `https:\u002F\u002F\u003Capp>.convex.app` URL anyone can open?\"\n\nPublish **only on a clear yes**. On a no, the app keeps running locally — done.\n\nOn yes, three parts (the served runbook has the full detail — it wins on conflict):\n\n**1. Rebind passkeys to the public page origin** (WebAuthn is origin-bound; the\npage moves to `\u003Capp>.convex.app` while the auth HTTP routes stay on the\ndeployment's `*.convex.site`). `\u003Capp>` = the deployment name (the subdomain of\n`NEXT_PUBLIC_CONVEX_URL`). Use the `NAME=VALUE` form (never `env set NAME \"$VALUE\"`\n— values starting with `-` parse as flags):\n\n```bash\nnpx convex env set \"SITE_URL=https:\u002F\u002F\u003Capp>.convex.app\"\nnpx convex env set \"AUTH_PASSKEY_RP_ID=\u003Capp>.convex.app\"\nnpx convex env set \"AUTH_PASSKEY_ORIGIN=https:\u002F\u002F\u003Capp>.convex.app\"\n```\n\n**2. Static export** — `next.config.ts` must be exactly\n`{ output: \"export\", images: { unoptimized: true } }` (never silence the linter or\ntype-checker to force a build — fix the real cause). Export emits to `out\u002F`.\n\n**3. Publish through the moderated gateway** (no static-hosting component needed):\n\n```bash\ncurl -fsSL https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fpublish-convex-app -o publish-convex-app.mjs\nnpm install -D fflate\nnode publish-convex-app.mjs            # build → zip out\u002F → moderated gateway upload\n```\n\nIt prints `https:\u002F\u002F\u003Capp>.convex.app` — pass that URL to the user, and verify the\npasskey ceremony works on the published page (register a test passkey; an\nRP-ID\u002Forigin error means the three env vars above don't match the `.convex.app`\nhost). If the gateway returns 403 (content moderation), it prints the reasons — a\nlegitimate app should pass; report a false positive to the user, don't evade it.\nPublishing needs a cloud Convex deployment; if anonymous\u002Flocal, `npx convex dev`\ninto a cloud project first.\n\n## STEP 4 — stay on watch with `fix_errors_automatically` (start EARLY, don't yield)\n\nThis harness has no push: a user request typed into the Chef panel or a runtime\nerror sits **unseen** until you actively look. This plugin bundles a `convex-plugin`\nMCP server with one **blocking** tool that surfaces it as an event and fixes it.\n\n**Start watching as soon as the app is open (right after STEP 1) — not just after\nv1.** The user is most engaged at the very start and will often submit a request or\nquestion while you're still building. Call `fix_errors_automatically` between build\nmilestones and whenever you'd otherwise pause; on the FIRST call it returns\n**immediately** if anything is already pending (it surfaces existing unhandled\nrequests\u002Fquestions as `existing: true`), so feedback submitted before you started\nwatching is never lost. Then make it your standing idle action for the rest of the\nsession.\n\n> **Avoid the repeated approval prompt:** each call is a separate tool invocation,\n> so a one-time \"Allow\" re-asks every loop. Choose **\"Always allow\"** when prompted,\n> or add to `~\u002F.codex\u002Fconfig.toml`: `[mcp_servers.convex-plugin]` then\n> `trust_level = \"trusted\"`. Also pass a long `timeoutMs` (e.g. 280000) so each\n> block is long and you re-call less often.\n\nCall the **`fix_errors_automatically`** tool with `projectDir` set to your app's\n**absolute path** (the `convex-app\u002F` subdir, where `.env.local` lives). It BLOCKS\nuntil the next event, then returns one of:\n- `feature_request` \u002F `refinement_answer` → the user wants something — handle it\n  (loop back through STEP 2\u002F3), then call the tool again.\n- `convex_error` \u002F `next_error` → stop, read the line, fix the file, wait for\n  `convex dev` \u002F Next to recover, then call again.\n- `quiet` → heartbeat timeout, nothing happened — just call it again.\n\n**Loop on this tool instead of ending your turn.** Each call blocks, so you stay on\nwatch and react within seconds — no polling, no walking away. Keep looping until the\nuser clearly says they're done.\n\n## After the run\n\nOffer `$improve-convex-plugin` so the user can send this session for an AI review that\nimproves the quickstart.\n\n## On failure \u002F friction — offer to self-report (WITH the user's permission)\n\nIf the run doesn't go smoothly — you give up, hit a blocker, it takes way too long, or\nthe user is frustrated — don't yield silently. **Ask first, send only on a yes**:\n\n> \"That didn't go as smoothly as it should have. May I send this session — the transcript,\n>  with secrets redacted — to the Convex team so they can fix what went wrong? [yes \u002F no]\"\n\n- **On yes** → run the `improve-convex-plugin` flow (ships the redacted transcript):\n  `curl -fsSL \"https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fsend-transcript\" | QB_HARNESS=codex bash -s -- --base https:\u002F\u002Fbasic-anteater-667.convex.site --idea \"\u003Cwhat broke>\"`\n- **On no** → respect it; send nothing.\n- Either way, give the user an honest summary of where it got stuck.\n\nNever send the transcript without an explicit yes.\n",{"data":39,"body":40},{"name":4,"description":6,"license":30},{"type":41,"children":42},"root",[43,52,103,123,151,158,170,246,252,455,461,482,488,508,1278,1334,1340,1360,1407,1525,1560,1608,1614,1619,1659,1664,1923,1928,1980,1986,1998,2013,2025,2030,2096,2202,2235,2245,2318,2346,2359,2386,2418,2470,2516,2573,2583,2589,2602,2608,2619,2633,2675,2680],{"type":44,"tag":45,"props":46,"children":48},"element","h1",{"id":47},"convex-labs-quickstart-labs-quickstart",[49],{"type":50,"value":51},"text","Convex Labs Quickstart ($labs-quickstart)",{"type":44,"tag":53,"props":54,"children":55},"p",{},[56,58,64,66,71,73,78,80,85,87,101],{"type":50,"value":57},"The ",{"type":44,"tag":59,"props":60,"children":61},"strong",{},[62],{"type":50,"value":63},"full",{"type":50,"value":65}," quickstart experience (labs): a running Next.js + shadcn \"wow-shell\"\nConvex app from one sentence, with ",{"type":44,"tag":59,"props":67,"children":68},{},[69],{"type":50,"value":70},"passkey sign-in",{"type":50,"value":72}," and the ",{"type":44,"tag":59,"props":74,"children":75},{},[76],{"type":50,"value":77},"Chef feedback\npanel",{"type":50,"value":79}," pre-baked, built live — and, once v1 works and ",{"type":44,"tag":59,"props":81,"children":82},{},[83],{"type":50,"value":84},"the user confirms",{"type":50,"value":86},",\n",{"type":44,"tag":59,"props":88,"children":89},{},[90,92,99],{"type":50,"value":91},"published to a public ",{"type":44,"tag":93,"props":94,"children":96},"code",{"className":95},[],[97],{"type":50,"value":98},"https:\u002F\u002F\u003Capp>.convex.app",{"type":50,"value":100}," URL",{"type":50,"value":102},". The heavy scaffold runs\nas a served shell script from the Convex quickstart backend (\"anteater\"); your job\nis to launch it, then build.",{"type":44,"tag":104,"props":105,"children":106},"blockquote",{},[107],{"type":44,"tag":53,"props":108,"children":109},{},[110,112,121],{"type":50,"value":111},"Want just a plain, local-only scaffold (no login, no panel, no publishing)?\nThat's the ",{"type":44,"tag":59,"props":113,"children":114},{},[115],{"type":44,"tag":93,"props":116,"children":118},{"className":117},[],[119],{"type":50,"value":120},"$quickstart",{"type":50,"value":122}," skill — use it instead.",{"type":44,"tag":53,"props":124,"children":125},{},[126,128,134,136,141,143,149],{"type":50,"value":127},"The user's request after ",{"type":44,"tag":93,"props":129,"children":131},{"className":130},[],[132],{"type":50,"value":133},"$labs-quickstart",{"type":50,"value":135}," is the ",{"type":44,"tag":59,"props":137,"children":138},{},[139],{"type":50,"value":140},"app idea",{"type":50,"value":142}," (e.g.\n",{"type":44,"tag":93,"props":144,"children":146},{"className":145},[],[147],{"type":50,"value":148},"$labs-quickstart a movie-night voting app",{"type":50,"value":150}," → idea = \"a movie-night voting app\").\nIf no idea was given, ask for a one-sentence idea, then continue.",{"type":44,"tag":152,"props":153,"children":155},"h2",{"id":154},"degradation-rule-when-the-scaffold-cant-run-write-code-not-ceremony",[156],{"type":50,"value":157},"Degradation rule — when the scaffold can't run, write code, not ceremony",{"type":44,"tag":53,"props":159,"children":160},{},[161,163,168],{"type":50,"value":162},"If the bootstrap can't run — a non-interactive\u002Fone-shot session, no network access, a\nsandboxed temp dir, or the user just wants code rather than a running app — ",{"type":44,"tag":59,"props":164,"children":165},{},[166],{"type":50,"value":167},"don't\nwait on the scaffold or the panel\u002Fpasskey\u002Fpublish machinery",{"type":50,"value":169},". Write a standard Convex\nproject directly:",{"type":44,"tag":171,"props":172,"children":173},"ul",{},[174,213],{"type":44,"tag":175,"props":176,"children":177},"li",{},[178,189,191,197,199,204,206,211],{"type":44,"tag":59,"props":179,"children":180},{},[181,183],{"type":50,"value":182},"ALL backend code goes under ",{"type":44,"tag":93,"props":184,"children":186},{"className":185},[],[187],{"type":50,"value":188},"convex\u002F",{"type":50,"value":190}," (",{"type":44,"tag":93,"props":192,"children":194},{"className":193},[],[195],{"type":50,"value":196},"schema.ts",{"type":50,"value":198},", queries, mutations, actions)\n— ",{"type":44,"tag":59,"props":200,"children":201},{},[202],{"type":50,"value":203},"NEVER at the project root.",{"type":50,"value":205}," Convex functions only run from the ",{"type":44,"tag":93,"props":207,"children":209},{"className":208},[],[210],{"type":50,"value":188},{"type":50,"value":212},"\ndirectory.",{"type":44,"tag":175,"props":214,"children":215},{},[216,221,223,229,231,237,238,244],{"type":44,"tag":59,"props":217,"children":218},{},[219],{"type":50,"value":220},"Write ZERO scaffold\u002Fdocumentation files",{"type":50,"value":222}," unless explicitly asked — no\n",{"type":44,"tag":93,"props":224,"children":226},{"className":225},[],[227],{"type":50,"value":228},"START_HERE.md",{"type":50,"value":230},", ",{"type":44,"tag":93,"props":232,"children":234},{"className":233},[],[235],{"type":50,"value":236},"ARCHITECTURE.md",{"type":50,"value":230},{"type":44,"tag":93,"props":239,"children":241},{"className":240},[],[242],{"type":50,"value":243},"MANIFEST.txt",{"type":50,"value":245},", or README walls. \"Build me a\nbackend\" is a request for code, not a design-doc package.",{"type":44,"tag":152,"props":247,"children":249},{"id":248},"data-access-imports-read-before-writing-any-convexts",[250],{"type":50,"value":251},"Data access + imports — read before writing any convex\u002F*.ts",{"type":44,"tag":171,"props":253,"children":254},{},[255,292,327,413,431],{"type":44,"tag":175,"props":256,"children":257},{},[258,260,266,268,274,276,282,284,290],{"type":50,"value":259},"Never an unbounded ",{"type":44,"tag":93,"props":261,"children":263},{"className":262},[],[264],{"type":50,"value":265},".collect()",{"type":50,"value":267}," on a table that can grow — use ",{"type":44,"tag":93,"props":269,"children":271},{"className":270},[],[272],{"type":50,"value":273},".withIndex(...)",{"type":50,"value":275}," +\n",{"type":44,"tag":93,"props":277,"children":279},{"className":278},[],[280],{"type":50,"value":281},".paginate(paginationOpts)",{"type":50,"value":283},"\u002F",{"type":44,"tag":93,"props":285,"children":287},{"className":286},[],[288],{"type":50,"value":289},".take(n)",{"type":50,"value":291},".",{"type":44,"tag":175,"props":293,"children":294},{},[295,297,303,305,310,312,317,319,325],{"type":50,"value":296},"Index, don't filter — ",{"type":44,"tag":93,"props":298,"children":300},{"className":299},[],[301],{"type":50,"value":302},".index(...)",{"type":50,"value":304}," in ",{"type":44,"tag":93,"props":306,"children":308},{"className":307},[],[309],{"type":50,"value":196},{"type":50,"value":311}," for every read path, queried via\n",{"type":44,"tag":93,"props":313,"children":315},{"className":314},[],[316],{"type":50,"value":273},{"type":50,"value":318},"; ",{"type":44,"tag":93,"props":320,"children":322},{"className":321},[],[323],{"type":50,"value":324},".filter()",{"type":50,"value":326}," is a full table scan.",{"type":44,"tag":175,"props":328,"children":329},{},[330,332,338,339,345,346,352,353,359,360,366,367,373,375,381,382,388,389,395,397,403,405,411],{"type":50,"value":331},"Imports: ",{"type":44,"tag":93,"props":333,"children":335},{"className":334},[],[336],{"type":50,"value":337},"query",{"type":50,"value":283},{"type":44,"tag":93,"props":340,"children":342},{"className":341},[],[343],{"type":50,"value":344},"mutation",{"type":50,"value":283},{"type":44,"tag":93,"props":347,"children":349},{"className":348},[],[350],{"type":50,"value":351},"action",{"type":50,"value":283},{"type":44,"tag":93,"props":354,"children":356},{"className":355},[],[357],{"type":50,"value":358},"internalQuery",{"type":50,"value":283},{"type":44,"tag":93,"props":361,"children":363},{"className":362},[],[364],{"type":50,"value":365},"internalMutation",{"type":50,"value":283},{"type":44,"tag":93,"props":368,"children":370},{"className":369},[],[371],{"type":50,"value":372},"internalAction",{"type":50,"value":374},"\nfrom ",{"type":44,"tag":93,"props":376,"children":378},{"className":377},[],[379],{"type":50,"value":380},"\".\u002F_generated\u002Fserver\"",{"type":50,"value":318},{"type":44,"tag":93,"props":383,"children":385},{"className":384},[],[386],{"type":50,"value":387},"api",{"type":50,"value":283},{"type":44,"tag":93,"props":390,"children":392},{"className":391},[],[393],{"type":50,"value":394},"internal",{"type":50,"value":396}," from ",{"type":44,"tag":93,"props":398,"children":400},{"className":399},[],[401],{"type":50,"value":402},"\".\u002F_generated\u002Fapi\"",{"type":50,"value":404},"; never from\n",{"type":44,"tag":93,"props":406,"children":408},{"className":407},[],[409],{"type":50,"value":410},"\"convex\u002Fserver\"",{"type":50,"value":412}," in application code.",{"type":44,"tag":175,"props":414,"children":415},{},[416,422,424,430],{"type":44,"tag":93,"props":417,"children":419},{"className":418},[],[420],{"type":50,"value":421},"v.literal(\"exact value\")",{"type":50,"value":423}," for fixed string\u002Fenum members, not a bare ",{"type":44,"tag":93,"props":425,"children":427},{"className":426},[],[428],{"type":50,"value":429},"v.string()",{"type":50,"value":291},{"type":44,"tag":175,"props":432,"children":433},{},[434,440,442,447,449,454],{"type":44,"tag":93,"props":435,"children":437},{"className":436},[],[438],{"type":50,"value":439},"\"use node\";",{"type":50,"value":441}," is action-only — never in a file that also exports a ",{"type":44,"tag":93,"props":443,"children":445},{"className":444},[],[446],{"type":50,"value":337},{"type":50,"value":448}," or\n",{"type":44,"tag":93,"props":450,"children":452},{"className":451},[],[453],{"type":50,"value":344},{"type":50,"value":291},{"type":44,"tag":152,"props":456,"children":458},{"id":457},"self-verify-before-declaring-backend-work-done",[459],{"type":50,"value":460},"Self-verify — before declaring backend work done",{"type":44,"tag":53,"props":462,"children":463},{},[464,466,472,474,480],{"type":50,"value":465},"Before you call any backend work finished: run ",{"type":44,"tag":93,"props":467,"children":469},{"className":468},[],[470],{"type":50,"value":471},"npx tsc --noEmit",{"type":50,"value":473}," and, when a\ndeployment is available (or via a local anonymous one:\n",{"type":44,"tag":93,"props":475,"children":477},{"className":476},[],[478],{"type":50,"value":479},"CONVEX_AGENT_MODE=anonymous npx convex dev --once",{"type":50,"value":481},"), push it. Fix every error\neither one reports before finishing — one verify round catches the\nwrong-relative-import \u002F duplicate-symbol \u002F unbalanced-paren class that otherwise\nbreaks the deploy.",{"type":44,"tag":152,"props":483,"children":485},{"id":484},"step-0-launch-the-scaffold-now-before-anything-else",[486],{"type":50,"value":487},"STEP 0 — launch the scaffold NOW (before anything else)",{"type":44,"tag":53,"props":489,"children":490},{},[491,493,498,500,506],{"type":50,"value":492},"Run this ",{"type":44,"tag":59,"props":494,"children":495},{},[496],{"type":50,"value":497},"first",{"type":50,"value":499},", before any reasoning or other tool calls — it kicks off the\n~45–120s scaffold (npm install, convex dev, next dev) in the background so it's\ninstalling while you read the rest. Substitute the user's idea for ",{"type":44,"tag":93,"props":501,"children":503},{"className":502},[],[504],{"type":50,"value":505},"\u003CIDEA>",{"type":50,"value":507},":",{"type":44,"tag":509,"props":510,"children":515},"pre",{"className":511,"code":512,"language":513,"meta":514,"style":514},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","BASE=\"https:\u002F\u002Fbasic-anteater-667.convex.site\"\nIDEA=\"\u003CIDEA>\"\nSLUG=$(curl -fsS --max-time 15 -X POST \"$BASE\u002Fgenerate\" -H 'content-type: application\u002Fjson' \\\n  --data \"$(node -e 'process.stdout.write(JSON.stringify({idea:process.argv[1],template:\"nextjs-shadcn\"}))' \"$IDEA\")\" \\\n  | node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(JSON.parse(s).id||\"\")}catch{}})') || true\necho \"SLUG=$SLUG\"\nQB=$(mktemp -t convex-qb-XXXX.sh)\ncurl -fsS --max-time 20 \"$BASE\u002Fquickstart-bootstrap\" -o \"$QB\" || { echo \"BOOTSTRAP_FETCH_FAILED\"; exit 3; }\n# The bootstrap is feature-flagged via a profile. LABS ships the FULL profile:\n# passkey auth pre-baked, the Chef feedback panel wired, and public *.convex.app\n# publishing enabled — EXCEPT custom domains, which stay off (QB_DOMAIN=0).\n# Only fall back from pre-baked passkeys if the idea asked for a different auth\n# method (else the agent rips it out mid-build). Emit AUTH_MODE for STEP 2.\nif printf '%s' \"$IDEA\" | grep -qiE 'oauth|google (sign|login|auth)|github (login|auth)|sso|saml|magic[ -]?link|password[- ]?only|email.?(\\+|and|\u002F).?password|clerk|workos|auth0|\\.tgz'; then echo \"AUTH_MODE=custom\"; else echo \"AUTH_MODE=passkeys\"; fi\n# QB_HARNESS=codex tags telemetry; QB_ARGS_BASE\u002FQB_FEEDBACK_URL keep the args +\n# panel feedback on the same host the slug was generated on.\nnohup env QB_PROFILE=full QB_DOMAIN=0 QB_HARNESS=codex QB_ARGS_BASE=\"$BASE\" QB_FEEDBACK_URL=\"$BASE\u002Ffeedback\" \\\n  bash \"$QB\" $SLUG > .quickstart-bootstrap.log 2>&1 &\necho \"SCAFFOLD_LAUNCHED log=.quickstart-bootstrap.log SLUG=$SLUG\"\n","bash","",[516],{"type":44,"tag":93,"props":517,"children":518},{"__ignoreMap":514},[519,553,577,667,722,770,797,830,937,947,956,965,974,983,1112,1121,1130,1207,1253],{"type":44,"tag":520,"props":521,"children":524},"span",{"class":522,"line":523},"line",1,[525,531,537,542,548],{"type":44,"tag":520,"props":526,"children":528},{"style":527},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[529],{"type":50,"value":530},"BASE",{"type":44,"tag":520,"props":532,"children":534},{"style":533},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[535],{"type":50,"value":536},"=",{"type":44,"tag":520,"props":538,"children":539},{"style":533},[540],{"type":50,"value":541},"\"",{"type":44,"tag":520,"props":543,"children":545},{"style":544},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[546],{"type":50,"value":547},"https:\u002F\u002Fbasic-anteater-667.convex.site",{"type":44,"tag":520,"props":549,"children":550},{"style":533},[551],{"type":50,"value":552},"\"\n",{"type":44,"tag":520,"props":554,"children":555},{"class":522,"line":27},[556,561,565,569,573],{"type":44,"tag":520,"props":557,"children":558},{"style":527},[559],{"type":50,"value":560},"IDEA",{"type":44,"tag":520,"props":562,"children":563},{"style":533},[564],{"type":50,"value":536},{"type":44,"tag":520,"props":566,"children":567},{"style":533},[568],{"type":50,"value":541},{"type":44,"tag":520,"props":570,"children":571},{"style":544},[572],{"type":50,"value":505},{"type":44,"tag":520,"props":574,"children":575},{"style":533},[576],{"type":50,"value":552},{"type":44,"tag":520,"props":578,"children":580},{"class":522,"line":579},3,[581,586,591,597,602,607,613,618,623,628,633,638,642,647,652,657,662],{"type":44,"tag":520,"props":582,"children":583},{"style":527},[584],{"type":50,"value":585},"SLUG",{"type":44,"tag":520,"props":587,"children":588},{"style":533},[589],{"type":50,"value":590},"=$(",{"type":44,"tag":520,"props":592,"children":594},{"style":593},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[595],{"type":50,"value":596},"curl",{"type":44,"tag":520,"props":598,"children":599},{"style":544},[600],{"type":50,"value":601}," -fsS",{"type":44,"tag":520,"props":603,"children":604},{"style":544},[605],{"type":50,"value":606}," --max-time",{"type":44,"tag":520,"props":608,"children":610},{"style":609},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[611],{"type":50,"value":612}," 15",{"type":44,"tag":520,"props":614,"children":615},{"style":544},[616],{"type":50,"value":617}," -X",{"type":44,"tag":520,"props":619,"children":620},{"style":544},[621],{"type":50,"value":622}," POST",{"type":44,"tag":520,"props":624,"children":625},{"style":533},[626],{"type":50,"value":627}," \"",{"type":44,"tag":520,"props":629,"children":630},{"style":527},[631],{"type":50,"value":632},"$BASE",{"type":44,"tag":520,"props":634,"children":635},{"style":544},[636],{"type":50,"value":637},"\u002Fgenerate",{"type":44,"tag":520,"props":639,"children":640},{"style":533},[641],{"type":50,"value":541},{"type":44,"tag":520,"props":643,"children":644},{"style":544},[645],{"type":50,"value":646}," -H",{"type":44,"tag":520,"props":648,"children":649},{"style":533},[650],{"type":50,"value":651}," '",{"type":44,"tag":520,"props":653,"children":654},{"style":544},[655],{"type":50,"value":656},"content-type: application\u002Fjson",{"type":44,"tag":520,"props":658,"children":659},{"style":533},[660],{"type":50,"value":661},"'",{"type":44,"tag":520,"props":663,"children":664},{"style":527},[665],{"type":50,"value":666}," \\\n",{"type":44,"tag":520,"props":668,"children":670},{"class":522,"line":669},4,[671,676,681,686,691,695,700,704,708,713,718],{"type":44,"tag":520,"props":672,"children":673},{"style":544},[674],{"type":50,"value":675},"  --data",{"type":44,"tag":520,"props":677,"children":678},{"style":533},[679],{"type":50,"value":680}," \"$(",{"type":44,"tag":520,"props":682,"children":683},{"style":593},[684],{"type":50,"value":685},"node",{"type":44,"tag":520,"props":687,"children":688},{"style":544},[689],{"type":50,"value":690}," -e ",{"type":44,"tag":520,"props":692,"children":693},{"style":533},[694],{"type":50,"value":661},{"type":44,"tag":520,"props":696,"children":697},{"style":544},[698],{"type":50,"value":699},"process.stdout.write(JSON.stringify({idea:process.argv[1],template:\"nextjs-shadcn\"}))",{"type":44,"tag":520,"props":701,"children":702},{"style":533},[703],{"type":50,"value":661},{"type":44,"tag":520,"props":705,"children":706},{"style":533},[707],{"type":50,"value":627},{"type":44,"tag":520,"props":709,"children":710},{"style":527},[711],{"type":50,"value":712},"$IDEA",{"type":44,"tag":520,"props":714,"children":715},{"style":533},[716],{"type":50,"value":717},"\")\"",{"type":44,"tag":520,"props":719,"children":720},{"style":527},[721],{"type":50,"value":666},{"type":44,"tag":520,"props":723,"children":725},{"class":522,"line":724},5,[726,731,736,741,745,750,754,759,764],{"type":44,"tag":520,"props":727,"children":728},{"style":533},[729],{"type":50,"value":730},"  |",{"type":44,"tag":520,"props":732,"children":733},{"style":593},[734],{"type":50,"value":735}," node",{"type":44,"tag":520,"props":737,"children":738},{"style":544},[739],{"type":50,"value":740}," -e",{"type":44,"tag":520,"props":742,"children":743},{"style":533},[744],{"type":50,"value":651},{"type":44,"tag":520,"props":746,"children":747},{"style":544},[748],{"type":50,"value":749},"let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(JSON.parse(s).id||\"\")}catch{}})",{"type":44,"tag":520,"props":751,"children":752},{"style":533},[753],{"type":50,"value":661},{"type":44,"tag":520,"props":755,"children":756},{"style":533},[757],{"type":50,"value":758},")",{"type":44,"tag":520,"props":760,"children":761},{"style":533},[762],{"type":50,"value":763}," ||",{"type":44,"tag":520,"props":765,"children":767},{"style":766},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[768],{"type":50,"value":769}," true\n",{"type":44,"tag":520,"props":771,"children":773},{"class":522,"line":772},6,[774,779,783,788,793],{"type":44,"tag":520,"props":775,"children":776},{"style":766},[777],{"type":50,"value":778},"echo",{"type":44,"tag":520,"props":780,"children":781},{"style":533},[782],{"type":50,"value":627},{"type":44,"tag":520,"props":784,"children":785},{"style":544},[786],{"type":50,"value":787},"SLUG=",{"type":44,"tag":520,"props":789,"children":790},{"style":527},[791],{"type":50,"value":792},"$SLUG",{"type":44,"tag":520,"props":794,"children":795},{"style":533},[796],{"type":50,"value":552},{"type":44,"tag":520,"props":798,"children":800},{"class":522,"line":799},7,[801,806,810,815,820,825],{"type":44,"tag":520,"props":802,"children":803},{"style":527},[804],{"type":50,"value":805},"QB",{"type":44,"tag":520,"props":807,"children":808},{"style":533},[809],{"type":50,"value":590},{"type":44,"tag":520,"props":811,"children":812},{"style":593},[813],{"type":50,"value":814},"mktemp",{"type":44,"tag":520,"props":816,"children":817},{"style":544},[818],{"type":50,"value":819}," -t",{"type":44,"tag":520,"props":821,"children":822},{"style":544},[823],{"type":50,"value":824}," convex-qb-XXXX.sh",{"type":44,"tag":520,"props":826,"children":827},{"style":533},[828],{"type":50,"value":829},")\n",{"type":44,"tag":520,"props":831,"children":833},{"class":522,"line":832},8,[834,838,842,846,851,855,859,864,868,873,877,882,886,890,895,900,904,909,913,918,923,928,932],{"type":44,"tag":520,"props":835,"children":836},{"style":593},[837],{"type":50,"value":596},{"type":44,"tag":520,"props":839,"children":840},{"style":544},[841],{"type":50,"value":601},{"type":44,"tag":520,"props":843,"children":844},{"style":544},[845],{"type":50,"value":606},{"type":44,"tag":520,"props":847,"children":848},{"style":609},[849],{"type":50,"value":850}," 20",{"type":44,"tag":520,"props":852,"children":853},{"style":533},[854],{"type":50,"value":627},{"type":44,"tag":520,"props":856,"children":857},{"style":527},[858],{"type":50,"value":632},{"type":44,"tag":520,"props":860,"children":861},{"style":544},[862],{"type":50,"value":863},"\u002Fquickstart-bootstrap",{"type":44,"tag":520,"props":865,"children":866},{"style":533},[867],{"type":50,"value":541},{"type":44,"tag":520,"props":869,"children":870},{"style":544},[871],{"type":50,"value":872}," -o",{"type":44,"tag":520,"props":874,"children":875},{"style":533},[876],{"type":50,"value":627},{"type":44,"tag":520,"props":878,"children":879},{"style":527},[880],{"type":50,"value":881},"$QB",{"type":44,"tag":520,"props":883,"children":884},{"style":533},[885],{"type":50,"value":541},{"type":44,"tag":520,"props":887,"children":888},{"style":533},[889],{"type":50,"value":763},{"type":44,"tag":520,"props":891,"children":892},{"style":533},[893],{"type":50,"value":894}," {",{"type":44,"tag":520,"props":896,"children":897},{"style":766},[898],{"type":50,"value":899}," echo",{"type":44,"tag":520,"props":901,"children":902},{"style":533},[903],{"type":50,"value":627},{"type":44,"tag":520,"props":905,"children":906},{"style":544},[907],{"type":50,"value":908},"BOOTSTRAP_FETCH_FAILED",{"type":44,"tag":520,"props":910,"children":911},{"style":533},[912],{"type":50,"value":541},{"type":44,"tag":520,"props":914,"children":915},{"style":533},[916],{"type":50,"value":917},";",{"type":44,"tag":520,"props":919,"children":920},{"style":766},[921],{"type":50,"value":922}," exit",{"type":44,"tag":520,"props":924,"children":925},{"style":609},[926],{"type":50,"value":927}," 3",{"type":44,"tag":520,"props":929,"children":930},{"style":533},[931],{"type":50,"value":917},{"type":44,"tag":520,"props":933,"children":934},{"style":533},[935],{"type":50,"value":936}," }\n",{"type":44,"tag":520,"props":938,"children":940},{"class":522,"line":939},9,[941],{"type":44,"tag":520,"props":942,"children":944},{"style":943},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[945],{"type":50,"value":946},"# The bootstrap is feature-flagged via a profile. LABS ships the FULL profile:\n",{"type":44,"tag":520,"props":948,"children":950},{"class":522,"line":949},10,[951],{"type":44,"tag":520,"props":952,"children":953},{"style":943},[954],{"type":50,"value":955},"# passkey auth pre-baked, the Chef feedback panel wired, and public *.convex.app\n",{"type":44,"tag":520,"props":957,"children":959},{"class":522,"line":958},11,[960],{"type":44,"tag":520,"props":961,"children":962},{"style":943},[963],{"type":50,"value":964},"# publishing enabled — EXCEPT custom domains, which stay off (QB_DOMAIN=0).\n",{"type":44,"tag":520,"props":966,"children":968},{"class":522,"line":967},12,[969],{"type":44,"tag":520,"props":970,"children":971},{"style":943},[972],{"type":50,"value":973},"# Only fall back from pre-baked passkeys if the idea asked for a different auth\n",{"type":44,"tag":520,"props":975,"children":977},{"class":522,"line":976},13,[978],{"type":44,"tag":520,"props":979,"children":980},{"style":943},[981],{"type":50,"value":982},"# method (else the agent rips it out mid-build). Emit AUTH_MODE for STEP 2.\n",{"type":44,"tag":520,"props":984,"children":986},{"class":522,"line":985},14,[987,993,998,1002,1007,1011,1015,1019,1023,1028,1033,1038,1042,1047,1051,1055,1060,1064,1068,1073,1077,1081,1086,1090,1094,1099,1103,1107],{"type":44,"tag":520,"props":988,"children":990},{"style":989},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[991],{"type":50,"value":992},"if",{"type":44,"tag":520,"props":994,"children":995},{"style":766},[996],{"type":50,"value":997}," printf",{"type":44,"tag":520,"props":999,"children":1000},{"style":533},[1001],{"type":50,"value":651},{"type":44,"tag":520,"props":1003,"children":1004},{"style":544},[1005],{"type":50,"value":1006},"%s",{"type":44,"tag":520,"props":1008,"children":1009},{"style":533},[1010],{"type":50,"value":661},{"type":44,"tag":520,"props":1012,"children":1013},{"style":533},[1014],{"type":50,"value":627},{"type":44,"tag":520,"props":1016,"children":1017},{"style":527},[1018],{"type":50,"value":712},{"type":44,"tag":520,"props":1020,"children":1021},{"style":533},[1022],{"type":50,"value":541},{"type":44,"tag":520,"props":1024,"children":1025},{"style":533},[1026],{"type":50,"value":1027}," |",{"type":44,"tag":520,"props":1029,"children":1030},{"style":593},[1031],{"type":50,"value":1032}," grep",{"type":44,"tag":520,"props":1034,"children":1035},{"style":544},[1036],{"type":50,"value":1037}," -qiE",{"type":44,"tag":520,"props":1039,"children":1040},{"style":533},[1041],{"type":50,"value":651},{"type":44,"tag":520,"props":1043,"children":1044},{"style":544},[1045],{"type":50,"value":1046},"oauth|google (sign|login|auth)|github (login|auth)|sso|saml|magic[ -]?link|password[- ]?only|email.?(\\+|and|\u002F).?password|clerk|workos|auth0|\\.tgz",{"type":44,"tag":520,"props":1048,"children":1049},{"style":533},[1050],{"type":50,"value":661},{"type":44,"tag":520,"props":1052,"children":1053},{"style":533},[1054],{"type":50,"value":917},{"type":44,"tag":520,"props":1056,"children":1057},{"style":989},[1058],{"type":50,"value":1059}," then",{"type":44,"tag":520,"props":1061,"children":1062},{"style":766},[1063],{"type":50,"value":899},{"type":44,"tag":520,"props":1065,"children":1066},{"style":533},[1067],{"type":50,"value":627},{"type":44,"tag":520,"props":1069,"children":1070},{"style":544},[1071],{"type":50,"value":1072},"AUTH_MODE=custom",{"type":44,"tag":520,"props":1074,"children":1075},{"style":533},[1076],{"type":50,"value":541},{"type":44,"tag":520,"props":1078,"children":1079},{"style":533},[1080],{"type":50,"value":917},{"type":44,"tag":520,"props":1082,"children":1083},{"style":989},[1084],{"type":50,"value":1085}," else",{"type":44,"tag":520,"props":1087,"children":1088},{"style":766},[1089],{"type":50,"value":899},{"type":44,"tag":520,"props":1091,"children":1092},{"style":533},[1093],{"type":50,"value":627},{"type":44,"tag":520,"props":1095,"children":1096},{"style":544},[1097],{"type":50,"value":1098},"AUTH_MODE=passkeys",{"type":44,"tag":520,"props":1100,"children":1101},{"style":533},[1102],{"type":50,"value":541},{"type":44,"tag":520,"props":1104,"children":1105},{"style":533},[1106],{"type":50,"value":917},{"type":44,"tag":520,"props":1108,"children":1109},{"style":989},[1110],{"type":50,"value":1111}," fi\n",{"type":44,"tag":520,"props":1113,"children":1115},{"class":522,"line":1114},15,[1116],{"type":44,"tag":520,"props":1117,"children":1118},{"style":943},[1119],{"type":50,"value":1120},"# QB_HARNESS=codex tags telemetry; QB_ARGS_BASE\u002FQB_FEEDBACK_URL keep the args +\n",{"type":44,"tag":520,"props":1122,"children":1124},{"class":522,"line":1123},16,[1125],{"type":44,"tag":520,"props":1126,"children":1127},{"style":943},[1128],{"type":50,"value":1129},"# panel feedback on the same host the slug was generated on.\n",{"type":44,"tag":520,"props":1131,"children":1133},{"class":522,"line":1132},17,[1134,1139,1144,1149,1154,1159,1164,1169,1173,1177,1181,1186,1190,1194,1199,1203],{"type":44,"tag":520,"props":1135,"children":1136},{"style":593},[1137],{"type":50,"value":1138},"nohup",{"type":44,"tag":520,"props":1140,"children":1141},{"style":544},[1142],{"type":50,"value":1143}," env",{"type":44,"tag":520,"props":1145,"children":1146},{"style":544},[1147],{"type":50,"value":1148}," QB_PROFILE=full",{"type":44,"tag":520,"props":1150,"children":1151},{"style":544},[1152],{"type":50,"value":1153}," QB_DOMAIN=",{"type":44,"tag":520,"props":1155,"children":1156},{"style":609},[1157],{"type":50,"value":1158},"0",{"type":44,"tag":520,"props":1160,"children":1161},{"style":544},[1162],{"type":50,"value":1163}," QB_HARNESS=codex",{"type":44,"tag":520,"props":1165,"children":1166},{"style":544},[1167],{"type":50,"value":1168}," QB_ARGS_BASE=",{"type":44,"tag":520,"props":1170,"children":1171},{"style":533},[1172],{"type":50,"value":541},{"type":44,"tag":520,"props":1174,"children":1175},{"style":527},[1176],{"type":50,"value":632},{"type":44,"tag":520,"props":1178,"children":1179},{"style":533},[1180],{"type":50,"value":541},{"type":44,"tag":520,"props":1182,"children":1183},{"style":544},[1184],{"type":50,"value":1185}," QB_FEEDBACK_URL=",{"type":44,"tag":520,"props":1187,"children":1188},{"style":533},[1189],{"type":50,"value":541},{"type":44,"tag":520,"props":1191,"children":1192},{"style":527},[1193],{"type":50,"value":632},{"type":44,"tag":520,"props":1195,"children":1196},{"style":544},[1197],{"type":50,"value":1198},"\u002Ffeedback",{"type":44,"tag":520,"props":1200,"children":1201},{"style":533},[1202],{"type":50,"value":541},{"type":44,"tag":520,"props":1204,"children":1205},{"style":527},[1206],{"type":50,"value":666},{"type":44,"tag":520,"props":1208,"children":1210},{"class":522,"line":1209},18,[1211,1216,1220,1224,1228,1233,1238,1243,1248],{"type":44,"tag":520,"props":1212,"children":1213},{"style":544},[1214],{"type":50,"value":1215},"  bash",{"type":44,"tag":520,"props":1217,"children":1218},{"style":533},[1219],{"type":50,"value":627},{"type":44,"tag":520,"props":1221,"children":1222},{"style":527},[1223],{"type":50,"value":881},{"type":44,"tag":520,"props":1225,"children":1226},{"style":533},[1227],{"type":50,"value":541},{"type":44,"tag":520,"props":1229,"children":1230},{"style":527},[1231],{"type":50,"value":1232}," $SLUG ",{"type":44,"tag":520,"props":1234,"children":1235},{"style":533},[1236],{"type":50,"value":1237},">",{"type":44,"tag":520,"props":1239,"children":1240},{"style":544},[1241],{"type":50,"value":1242}," .quickstart-bootstrap.log",{"type":44,"tag":520,"props":1244,"children":1245},{"style":533},[1246],{"type":50,"value":1247}," 2>&1",{"type":44,"tag":520,"props":1249,"children":1250},{"style":533},[1251],{"type":50,"value":1252}," &\n",{"type":44,"tag":520,"props":1254,"children":1256},{"class":522,"line":1255},19,[1257,1261,1265,1270,1274],{"type":44,"tag":520,"props":1258,"children":1259},{"style":766},[1260],{"type":50,"value":778},{"type":44,"tag":520,"props":1262,"children":1263},{"style":533},[1264],{"type":50,"value":627},{"type":44,"tag":520,"props":1266,"children":1267},{"style":544},[1268],{"type":50,"value":1269},"SCAFFOLD_LAUNCHED log=.quickstart-bootstrap.log SLUG=",{"type":44,"tag":520,"props":1271,"children":1272},{"style":527},[1273],{"type":50,"value":792},{"type":44,"tag":520,"props":1275,"children":1276},{"style":533},[1277],{"type":50,"value":552},{"type":44,"tag":171,"props":1279,"children":1280},{},[1281,1307],{"type":44,"tag":175,"props":1282,"children":1283},{},[1284,1286,1292,1294,1299,1301,1306],{"type":50,"value":1285},"If it prints ",{"type":44,"tag":93,"props":1287,"children":1289},{"className":1288},[],[1290],{"type":50,"value":1291},"SCAFFOLD_LAUNCHED",{"type":50,"value":1293},", the scaffold is running in the background.\n",{"type":44,"tag":59,"props":1295,"children":1296},{},[1297],{"type":50,"value":1298},"Do NOT run it again.",{"type":50,"value":1300}," Note the ",{"type":44,"tag":93,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":50,"value":787},{"type":50,"value":291},{"type":44,"tag":175,"props":1308,"children":1309},{},[1310,1312,1317,1319,1324,1326,1332],{"type":50,"value":1311},"If ",{"type":44,"tag":93,"props":1313,"children":1315},{"className":1314},[],[1316],{"type":50,"value":596},{"type":50,"value":1318}," is blocked or you see ",{"type":44,"tag":93,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":50,"value":908},{"type":50,"value":1325},", the network\u002Fsandbox\nblocked it — tell the user they likely need to run Codex with network access \u002F\nauto-approve (",{"type":44,"tag":93,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":50,"value":1331},"codex --sandbox danger-full-access",{"type":50,"value":1333},"), then retry.",{"type":44,"tag":152,"props":1335,"children":1337},{"id":1336},"step-1-wait-for-the-scaffold-open-the-browser",[1338],{"type":50,"value":1339},"STEP 1 — wait for the scaffold, open the browser",{"type":44,"tag":53,"props":1341,"children":1342},{},[1343,1345,1351,1353,1359],{"type":50,"value":1344},"Poll ",{"type":44,"tag":93,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":50,"value":1350},".quickstart-bootstrap.log",{"type":50,"value":1352}," until it contains ",{"type":44,"tag":93,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":50,"value":1358},"BOOTSTRAP_COMPLETE",{"type":50,"value":291},{"type":44,"tag":53,"props":1361,"children":1362},{},[1363,1376,1378,1383,1385,1390,1392,1397,1399,1405],{"type":44,"tag":59,"props":1364,"children":1365},{},[1366,1368,1374],{"type":50,"value":1367},"Codex's sandbox often reaps backgrounded (",{"type":44,"tag":93,"props":1369,"children":1371},{"className":1370},[],[1372],{"type":50,"value":1373},"nohup … &",{"type":50,"value":1375},") processes when the launch\ncall returns",{"type":50,"value":1377}," — so the bootstrap may write its first line, then die before scaffolding.\nIf within ~20s the log has stalled (no new lines), ",{"type":44,"tag":59,"props":1379,"children":1380},{},[1381],{"type":50,"value":1382},"no app subdirectory has appeared",{"type":50,"value":1384},",\nand there's no ",{"type":44,"tag":93,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":50,"value":1358},{"type":50,"value":1391},", the background launch was reaped. Recover by running\nthe bootstrap in the ",{"type":44,"tag":59,"props":1393,"children":1394},{},[1395],{"type":50,"value":1396},"FOREGROUND",{"type":50,"value":1398}," — re-run the STEP 0 block but replace the\n",{"type":44,"tag":93,"props":1400,"children":1402},{"className":1401},[],[1403],{"type":50,"value":1404},"nohup env … &",{"type":50,"value":1406}," line with a plain foreground run, same env:",{"type":44,"tag":509,"props":1408,"children":1410},{"className":511,"code":1409,"language":513,"meta":514,"style":514},"QB_PROFILE=full QB_DOMAIN=0 QB_HARNESS=codex QB_ARGS_BASE=\"$BASE\" QB_FEEDBACK_URL=\"$BASE\u002Ffeedback\" bash \"$QB\" $SLUG\n",[1411],{"type":44,"tag":93,"props":1412,"children":1413},{"__ignoreMap":514},[1414],{"type":44,"tag":520,"props":1415,"children":1416},{"class":522,"line":523},[1417,1422,1426,1430,1435,1439,1443,1448,1452,1457,1462,1466,1470,1474,1478,1483,1487,1491,1495,1499,1503,1508,1512,1516,1520],{"type":44,"tag":520,"props":1418,"children":1419},{"style":527},[1420],{"type":50,"value":1421},"QB_PROFILE",{"type":44,"tag":520,"props":1423,"children":1424},{"style":533},[1425],{"type":50,"value":536},{"type":44,"tag":520,"props":1427,"children":1428},{"style":544},[1429],{"type":50,"value":63},{"type":44,"tag":520,"props":1431,"children":1432},{"style":527},[1433],{"type":50,"value":1434}," QB_DOMAIN",{"type":44,"tag":520,"props":1436,"children":1437},{"style":533},[1438],{"type":50,"value":536},{"type":44,"tag":520,"props":1440,"children":1441},{"style":544},[1442],{"type":50,"value":1158},{"type":44,"tag":520,"props":1444,"children":1445},{"style":527},[1446],{"type":50,"value":1447}," QB_HARNESS",{"type":44,"tag":520,"props":1449,"children":1450},{"style":533},[1451],{"type":50,"value":536},{"type":44,"tag":520,"props":1453,"children":1454},{"style":544},[1455],{"type":50,"value":1456},"codex",{"type":44,"tag":520,"props":1458,"children":1459},{"style":527},[1460],{"type":50,"value":1461}," QB_ARGS_BASE",{"type":44,"tag":520,"props":1463,"children":1464},{"style":533},[1465],{"type":50,"value":536},{"type":44,"tag":520,"props":1467,"children":1468},{"style":533},[1469],{"type":50,"value":541},{"type":44,"tag":520,"props":1471,"children":1472},{"style":527},[1473],{"type":50,"value":632},{"type":44,"tag":520,"props":1475,"children":1476},{"style":533},[1477],{"type":50,"value":541},{"type":44,"tag":520,"props":1479,"children":1480},{"style":527},[1481],{"type":50,"value":1482}," QB_FEEDBACK_URL",{"type":44,"tag":520,"props":1484,"children":1485},{"style":533},[1486],{"type":50,"value":536},{"type":44,"tag":520,"props":1488,"children":1489},{"style":533},[1490],{"type":50,"value":541},{"type":44,"tag":520,"props":1492,"children":1493},{"style":527},[1494],{"type":50,"value":632},{"type":44,"tag":520,"props":1496,"children":1497},{"style":544},[1498],{"type":50,"value":1198},{"type":44,"tag":520,"props":1500,"children":1501},{"style":533},[1502],{"type":50,"value":541},{"type":44,"tag":520,"props":1504,"children":1505},{"style":593},[1506],{"type":50,"value":1507}," bash",{"type":44,"tag":520,"props":1509,"children":1510},{"style":533},[1511],{"type":50,"value":627},{"type":44,"tag":520,"props":1513,"children":1514},{"style":527},[1515],{"type":50,"value":881},{"type":44,"tag":520,"props":1517,"children":1518},{"style":533},[1519],{"type":50,"value":541},{"type":44,"tag":520,"props":1521,"children":1522},{"style":527},[1523],{"type":50,"value":1524}," $SLUG\n",{"type":44,"tag":53,"props":1526,"children":1527},{},[1528,1530,1536,1538,1544,1546,1551,1553,1558],{"type":50,"value":1529},"It backgrounds ",{"type":44,"tag":93,"props":1531,"children":1533},{"className":1532},[],[1534],{"type":50,"value":1535},"convex dev",{"type":50,"value":1537}," \u002F ",{"type":44,"tag":93,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":50,"value":1543},"next dev",{"type":50,"value":1545}," itself and returns at ",{"type":44,"tag":93,"props":1547,"children":1549},{"className":1548},[],[1550],{"type":50,"value":1358},{"type":50,"value":1552}," in\n~1–2 min (set a generous command timeout, 300s+). ",{"type":44,"tag":93,"props":1554,"children":1556},{"className":1555},[],[1557],{"type":50,"value":908},{"type":50,"value":1559}," → server\nunreachable; tell the user. When it completes the log prints:",{"type":44,"tag":171,"props":1561,"children":1562},{},[1563,1574],{"type":44,"tag":175,"props":1564,"children":1565},{},[1566,1572],{"type":44,"tag":93,"props":1567,"children":1569},{"className":1568},[],[1570],{"type":50,"value":1571},"OPEN_BROWSER_URL: http:\u002F\u002Flocalhost:\u003Cport>",{"type":50,"value":1573}," — open this for the user immediately.",{"type":44,"tag":175,"props":1575,"children":1576},{},[1577,1579,1584,1586,1591,1593,1599,1600,1606],{"type":50,"value":1578},"The app is scaffolded in a new subdirectory with ",{"type":44,"tag":93,"props":1580,"children":1582},{"className":1581},[],[1583],{"type":50,"value":1535},{"type":50,"value":1585}," + ",{"type":44,"tag":93,"props":1587,"children":1589},{"className":1588},[],[1590],{"type":50,"value":1543},{"type":50,"value":1592}," running\nand error watchers armed (",{"type":44,"tag":93,"props":1594,"children":1596},{"className":1595},[],[1597],{"type":50,"value":1598},"convex-errors.log",{"type":50,"value":1537},{"type":44,"tag":93,"props":1601,"children":1603},{"className":1602},[],[1604],{"type":50,"value":1605},"next-errors.log",{"type":50,"value":1607}," paths are in the log).",{"type":44,"tag":152,"props":1609,"children":1611},{"id":1610},"step-2-read-the-runbook-build-the-idea-live",[1612],{"type":50,"value":1613},"STEP 2 — read the runbook + build the idea live",{"type":44,"tag":53,"props":1615,"children":1616},{},[1617],{"type":50,"value":1618},"Read the personalized runbook for the full build flow (it's served — fetch it):",{"type":44,"tag":509,"props":1620,"children":1622},{"className":511,"code":1621,"language":513,"meta":514,"style":514},"curl -fsS \"https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fq\u002F$SLUG.md\"\n",[1623],{"type":44,"tag":93,"props":1624,"children":1625},{"__ignoreMap":514},[1626],{"type":44,"tag":520,"props":1627,"children":1628},{"class":522,"line":523},[1629,1633,1637,1641,1646,1650,1655],{"type":44,"tag":520,"props":1630,"children":1631},{"style":593},[1632],{"type":50,"value":596},{"type":44,"tag":520,"props":1634,"children":1635},{"style":544},[1636],{"type":50,"value":601},{"type":44,"tag":520,"props":1638,"children":1639},{"style":533},[1640],{"type":50,"value":627},{"type":44,"tag":520,"props":1642,"children":1643},{"style":544},[1644],{"type":50,"value":1645},"https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fq\u002F",{"type":44,"tag":520,"props":1647,"children":1648},{"style":527},[1649],{"type":50,"value":792},{"type":44,"tag":520,"props":1651,"children":1652},{"style":544},[1653],{"type":50,"value":1654},".md",{"type":44,"tag":520,"props":1656,"children":1657},{"style":533},[1658],{"type":50,"value":552},{"type":44,"tag":53,"props":1660,"children":1661},{},[1662],{"type":50,"value":1663},"Then build the user's idea following it. What's already done by the scaffold:",{"type":44,"tag":171,"props":1665,"children":1666},{},[1667,1812,1897],{"type":44,"tag":175,"props":1668,"children":1669},{},[1670,1675,1677,1683,1685,1690,1692,1697,1699,1704,1706,1712,1714,1719,1721,1726,1728,1734,1736,1742,1743,1749,1750,1756,1758,1763,1765,1771,1773,1779,1781,1787,1789,1795,1797,1803,1805,1811],{"type":44,"tag":59,"props":1671,"children":1672},{},[1673],{"type":50,"value":1674},"Auth:",{"type":50,"value":1676}," check ",{"type":44,"tag":93,"props":1678,"children":1680},{"className":1679},[],[1681],{"type":50,"value":1682},"AUTH_MODE",{"type":50,"value":1684}," in the launch log. If ",{"type":44,"tag":93,"props":1686,"children":1688},{"className":1687},[],[1689],{"type":50,"value":1072},{"type":50,"value":1691}," (the idea\nasked for OAuth\u002Fpassword\u002Fmagic-link\u002Fa specific auth component), passkeys were NOT\npre-baked — wire the ",{"type":44,"tag":59,"props":1693,"children":1694},{},[1695],{"type":50,"value":1696},"requested",{"type":50,"value":1698}," provider per its README (delegate ",{"type":44,"tag":93,"props":1700,"children":1702},{"className":1701},[],[1703],{"type":50,"value":188},{"type":50,"value":1705}," code\nto the ",{"type":44,"tag":93,"props":1707,"children":1709},{"className":1708},[],[1710],{"type":50,"value":1711},"convex-expert",{"type":50,"value":1713}," skill) and skip the passkey button. If ",{"type":44,"tag":93,"props":1715,"children":1717},{"className":1716},[],[1718],{"type":50,"value":1098},{"type":50,"value":1720},"\n(default), ",{"type":44,"tag":59,"props":1722,"children":1723},{},[1724],{"type":50,"value":1725},"passkeys",{"type":50,"value":1727}," are pre-baked (",{"type":44,"tag":93,"props":1729,"children":1731},{"className":1730},[],[1732],{"type":50,"value":1733},"@convex-dev\u002Fauth",{"type":50,"value":1735}," pinned build,\n",{"type":44,"tag":93,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":50,"value":1741},"convex\u002Fauth.ts",{"type":50,"value":230},{"type":44,"tag":93,"props":1744,"children":1746},{"className":1745},[],[1747],{"type":50,"value":1748},"...authTables",{"type":50,"value":230},{"type":44,"tag":93,"props":1751,"children":1753},{"className":1752},[],[1754],{"type":50,"value":1755},"ConvexAuthProvider",{"type":50,"value":1757},", JWT keys set) — you add the\n",{"type":44,"tag":59,"props":1759,"children":1760},{},[1761],{"type":50,"value":1762},"email-first sign-in UI",{"type":50,"value":1764},": an email input + one call to\n",{"type":44,"tag":93,"props":1766,"children":1768},{"className":1767},[],[1769],{"type":50,"value":1770},"usePasskeyAuth().signInOrRegisterWithPasskey({ email })",{"type":50,"value":1772},", which signs the user in if\nthey already have a passkey for that email or registers a new one (the build enables\nenumeration-by-email + autofill). Use the returned ",{"type":44,"tag":93,"props":1774,"children":1776},{"className":1775},[],[1777],{"type":50,"value":1778},"registered",{"type":50,"value":1780}," flag for the\nwelcome message; give the input ",{"type":44,"tag":93,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":50,"value":1786},"autoComplete=\"username webauthn\"",{"type":50,"value":1788}," for autofill.\n⚠ The email is self-asserted\u002Funverified — authorize off the Convex user ",{"type":44,"tag":93,"props":1790,"children":1792},{"className":1791},[],[1793],{"type":50,"value":1794},"_id",{"type":50,"value":1796},"\n(",{"type":44,"tag":93,"props":1798,"children":1800},{"className":1799},[],[1801],{"type":50,"value":1802},"getAuthUserId",{"type":50,"value":1804},"), never ",{"type":44,"tag":93,"props":1806,"children":1808},{"className":1807},[],[1809],{"type":50,"value":1810},"user.email",{"type":50,"value":291},{"type":44,"tag":175,"props":1813,"children":1814},{},[1815,1816,1821,1823,1829,1831,1837,1838,1844,1846,1851,1853,1858,1860,1866,1867,1873,1874,1880,1882,1888,1890,1896],{"type":50,"value":57},{"type":44,"tag":59,"props":1817,"children":1818},{},[1819],{"type":50,"value":1820},"Chef feedback panel",{"type":50,"value":1822}," is wired — keep the ",{"type":44,"tag":93,"props":1824,"children":1826},{"className":1825},[],[1827],{"type":50,"value":1828},"FeatureRequestPanel",{"type":50,"value":1830}," mount (a\nfloating panel in the layout, e.g. ",{"type":44,"tag":93,"props":1832,"children":1834},{"className":1833},[],[1835],{"type":50,"value":1836},"app\u002F_chef-panel.tsx",{"type":50,"value":1537},{"type":44,"tag":93,"props":1839,"children":1841},{"className":1840},[],[1842],{"type":50,"value":1843},"\u003CChefPanel \u002F>",{"type":50,"value":1845},") — ",{"type":44,"tag":59,"props":1847,"children":1848},{},[1849],{"type":50,"value":1850},"never\ndelete or unmount it",{"type":50,"value":1852},". ",{"type":44,"tag":59,"props":1854,"children":1855},{},[1856],{"type":50,"value":1857},"Narrate your build through the panel, not chat",{"type":50,"value":1859}," —\n",{"type":44,"tag":93,"props":1861,"children":1863},{"className":1862},[],[1864],{"type":50,"value":1865},"npx convex run progress:post '{\"message\":\"…\"}'",{"type":50,"value":86},{"type":44,"tag":93,"props":1868,"children":1870},{"className":1869},[],[1871],{"type":50,"value":1872},"npx convex run todos:plan '{\"items\":[…]}'",{"type":50,"value":1537},{"type":44,"tag":93,"props":1875,"children":1877},{"className":1876},[],[1878],{"type":50,"value":1879},"todos:advance",{"type":50,"value":1881},", ask the user\nclarifying questions with ",{"type":44,"tag":93,"props":1883,"children":1885},{"className":1884},[],[1886],{"type":50,"value":1887},"npx convex run refinementQuestions:ask '{\"text\":\"…\"}'",{"type":50,"value":1889},",\nand resolve incoming feature requests with\n",{"type":44,"tag":93,"props":1891,"children":1893},{"className":1892},[],[1894],{"type":50,"value":1895},"npx convex run featureRequests:setState '{\"id\":\"…\",\"state\":\"…\"}'",{"type":50,"value":291},{"type":44,"tag":175,"props":1898,"children":1899},{},[1900,1905,1907,1913,1915,1921],{"type":44,"tag":59,"props":1901,"children":1902},{},[1903],{"type":50,"value":1904},"Custom domains are NOT part of this release",{"type":50,"value":1906}," — don't brainstorm, offer, or\nregister domains, and don't look for ",{"type":44,"tag":93,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":50,"value":1912},".quickstart-domains.json",{"type":50,"value":1914},". (If the user\nalready owns a domain and asks to wire it, that's the separate ",{"type":44,"tag":93,"props":1916,"children":1918},{"className":1917},[],[1919],{"type":50,"value":1920},"$domains",{"type":50,"value":1922}," skill.)",{"type":44,"tag":53,"props":1924,"children":1925},{},[1926],{"type":50,"value":1927},"Rules while building:",{"type":44,"tag":171,"props":1929,"children":1930},{},[1931,1953],{"type":44,"tag":175,"props":1932,"children":1933},{},[1934,1936,1941,1943,1951],{"type":50,"value":1935},"Delegate all code inside ",{"type":44,"tag":93,"props":1937,"children":1939},{"className":1938},[],[1940],{"type":50,"value":188},{"type":50,"value":1942}," to the ",{"type":44,"tag":59,"props":1944,"children":1945},{},[1946],{"type":44,"tag":93,"props":1947,"children":1949},{"className":1948},[],[1950],{"type":50,"value":1711},{"type":50,"value":1952}," skill's rules\n(object-form syntax, validators, indexes, internal vs public).",{"type":44,"tag":175,"props":1954,"children":1955},{},[1956,1958,1963,1964,1970,1972,1978],{"type":50,"value":1957},"Watch for ",{"type":44,"tag":93,"props":1959,"children":1961},{"className":1960},[],[1962],{"type":50,"value":188},{"type":50,"value":1585},{"type":44,"tag":93,"props":1965,"children":1967},{"className":1966},[],[1968],{"type":50,"value":1969},"next",{"type":50,"value":1971}," errors and fix them as they appear — the easiest way\nis the ",{"type":44,"tag":93,"props":1973,"children":1975},{"className":1974},[],[1976],{"type":50,"value":1977},"fix_errors_automatically",{"type":50,"value":1979}," tool (see STEP 4), which surfaces them as events.",{"type":44,"tag":152,"props":1981,"children":1983},{"id":1982},"step-3-publish-to-convexapp-ask-the-user-first",[1984],{"type":50,"value":1985},"STEP 3 — publish to *.convex.app (ASK THE USER FIRST)",{"type":44,"tag":53,"props":1987,"children":1988},{},[1989,1991,1996],{"type":50,"value":1990},"When the app builds clean and the core feature works (your \"v1\"), ",{"type":44,"tag":59,"props":1992,"children":1993},{},[1994],{"type":50,"value":1995},"offer to\npublish",{"type":50,"value":1997}," — do not publish silently:",{"type":44,"tag":104,"props":1999,"children":2000},{},[2001],{"type":44,"tag":53,"props":2002,"children":2003},{},[2004,2006,2011],{"type":50,"value":2005},"\"v1 is working locally. Want me to publish it to a public\n",{"type":44,"tag":93,"props":2007,"children":2009},{"className":2008},[],[2010],{"type":50,"value":98},{"type":50,"value":2012}," URL anyone can open?\"",{"type":44,"tag":53,"props":2014,"children":2015},{},[2016,2018,2023],{"type":50,"value":2017},"Publish ",{"type":44,"tag":59,"props":2019,"children":2020},{},[2021],{"type":50,"value":2022},"only on a clear yes",{"type":50,"value":2024},". On a no, the app keeps running locally — done.",{"type":44,"tag":53,"props":2026,"children":2027},{},[2028],{"type":50,"value":2029},"On yes, three parts (the served runbook has the full detail — it wins on conflict):",{"type":44,"tag":53,"props":2031,"children":2032},{},[2033,2038,2040,2046,2048,2054,2056,2062,2064,2070,2072,2078,2080,2086,2088,2094],{"type":44,"tag":59,"props":2034,"children":2035},{},[2036],{"type":50,"value":2037},"1. Rebind passkeys to the public page origin",{"type":50,"value":2039}," (WebAuthn is origin-bound; the\npage moves to ",{"type":44,"tag":93,"props":2041,"children":2043},{"className":2042},[],[2044],{"type":50,"value":2045},"\u003Capp>.convex.app",{"type":50,"value":2047}," while the auth HTTP routes stay on the\ndeployment's ",{"type":44,"tag":93,"props":2049,"children":2051},{"className":2050},[],[2052],{"type":50,"value":2053},"*.convex.site",{"type":50,"value":2055},"). ",{"type":44,"tag":93,"props":2057,"children":2059},{"className":2058},[],[2060],{"type":50,"value":2061},"\u003Capp>",{"type":50,"value":2063}," = the deployment name (the subdomain of\n",{"type":44,"tag":93,"props":2065,"children":2067},{"className":2066},[],[2068],{"type":50,"value":2069},"NEXT_PUBLIC_CONVEX_URL",{"type":50,"value":2071},"). Use the ",{"type":44,"tag":93,"props":2073,"children":2075},{"className":2074},[],[2076],{"type":50,"value":2077},"NAME=VALUE",{"type":50,"value":2079}," form (never ",{"type":44,"tag":93,"props":2081,"children":2083},{"className":2082},[],[2084],{"type":50,"value":2085},"env set NAME \"$VALUE\"",{"type":50,"value":2087},"\n— values starting with ",{"type":44,"tag":93,"props":2089,"children":2091},{"className":2090},[],[2092],{"type":50,"value":2093},"-",{"type":50,"value":2095}," parse as flags):",{"type":44,"tag":509,"props":2097,"children":2099},{"className":511,"code":2098,"language":513,"meta":514,"style":514},"npx convex env set \"SITE_URL=https:\u002F\u002F\u003Capp>.convex.app\"\nnpx convex env set \"AUTH_PASSKEY_RP_ID=\u003Capp>.convex.app\"\nnpx convex env set \"AUTH_PASSKEY_ORIGIN=https:\u002F\u002F\u003Capp>.convex.app\"\n",[2100],{"type":44,"tag":93,"props":2101,"children":2102},{"__ignoreMap":514},[2103,2138,2170],{"type":44,"tag":520,"props":2104,"children":2105},{"class":522,"line":523},[2106,2111,2116,2120,2125,2129,2134],{"type":44,"tag":520,"props":2107,"children":2108},{"style":593},[2109],{"type":50,"value":2110},"npx",{"type":44,"tag":520,"props":2112,"children":2113},{"style":544},[2114],{"type":50,"value":2115}," convex",{"type":44,"tag":520,"props":2117,"children":2118},{"style":544},[2119],{"type":50,"value":1143},{"type":44,"tag":520,"props":2121,"children":2122},{"style":544},[2123],{"type":50,"value":2124}," set",{"type":44,"tag":520,"props":2126,"children":2127},{"style":533},[2128],{"type":50,"value":627},{"type":44,"tag":520,"props":2130,"children":2131},{"style":544},[2132],{"type":50,"value":2133},"SITE_URL=https:\u002F\u002F\u003Capp>.convex.app",{"type":44,"tag":520,"props":2135,"children":2136},{"style":533},[2137],{"type":50,"value":552},{"type":44,"tag":520,"props":2139,"children":2140},{"class":522,"line":27},[2141,2145,2149,2153,2157,2161,2166],{"type":44,"tag":520,"props":2142,"children":2143},{"style":593},[2144],{"type":50,"value":2110},{"type":44,"tag":520,"props":2146,"children":2147},{"style":544},[2148],{"type":50,"value":2115},{"type":44,"tag":520,"props":2150,"children":2151},{"style":544},[2152],{"type":50,"value":1143},{"type":44,"tag":520,"props":2154,"children":2155},{"style":544},[2156],{"type":50,"value":2124},{"type":44,"tag":520,"props":2158,"children":2159},{"style":533},[2160],{"type":50,"value":627},{"type":44,"tag":520,"props":2162,"children":2163},{"style":544},[2164],{"type":50,"value":2165},"AUTH_PASSKEY_RP_ID=\u003Capp>.convex.app",{"type":44,"tag":520,"props":2167,"children":2168},{"style":533},[2169],{"type":50,"value":552},{"type":44,"tag":520,"props":2171,"children":2172},{"class":522,"line":579},[2173,2177,2181,2185,2189,2193,2198],{"type":44,"tag":520,"props":2174,"children":2175},{"style":593},[2176],{"type":50,"value":2110},{"type":44,"tag":520,"props":2178,"children":2179},{"style":544},[2180],{"type":50,"value":2115},{"type":44,"tag":520,"props":2182,"children":2183},{"style":544},[2184],{"type":50,"value":1143},{"type":44,"tag":520,"props":2186,"children":2187},{"style":544},[2188],{"type":50,"value":2124},{"type":44,"tag":520,"props":2190,"children":2191},{"style":533},[2192],{"type":50,"value":627},{"type":44,"tag":520,"props":2194,"children":2195},{"style":544},[2196],{"type":50,"value":2197},"AUTH_PASSKEY_ORIGIN=https:\u002F\u002F\u003Capp>.convex.app",{"type":44,"tag":520,"props":2199,"children":2200},{"style":533},[2201],{"type":50,"value":552},{"type":44,"tag":53,"props":2203,"children":2204},{},[2205,2210,2212,2218,2220,2226,2228,2234],{"type":44,"tag":59,"props":2206,"children":2207},{},[2208],{"type":50,"value":2209},"2. Static export",{"type":50,"value":2211}," — ",{"type":44,"tag":93,"props":2213,"children":2215},{"className":2214},[],[2216],{"type":50,"value":2217},"next.config.ts",{"type":50,"value":2219}," must be exactly\n",{"type":44,"tag":93,"props":2221,"children":2223},{"className":2222},[],[2224],{"type":50,"value":2225},"{ output: \"export\", images: { unoptimized: true } }",{"type":50,"value":2227}," (never silence the linter or\ntype-checker to force a build — fix the real cause). Export emits to ",{"type":44,"tag":93,"props":2229,"children":2231},{"className":2230},[],[2232],{"type":50,"value":2233},"out\u002F",{"type":50,"value":291},{"type":44,"tag":53,"props":2236,"children":2237},{},[2238,2243],{"type":44,"tag":59,"props":2239,"children":2240},{},[2241],{"type":50,"value":2242},"3. Publish through the moderated gateway",{"type":50,"value":2244}," (no static-hosting component needed):",{"type":44,"tag":509,"props":2246,"children":2248},{"className":511,"code":2247,"language":513,"meta":514,"style":514},"curl -fsSL https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fpublish-convex-app -o publish-convex-app.mjs\nnpm install -D fflate\nnode publish-convex-app.mjs            # build → zip out\u002F → moderated gateway upload\n",[2249],{"type":44,"tag":93,"props":2250,"children":2251},{"__ignoreMap":514},[2252,2278,2301],{"type":44,"tag":520,"props":2253,"children":2254},{"class":522,"line":523},[2255,2259,2264,2269,2273],{"type":44,"tag":520,"props":2256,"children":2257},{"style":593},[2258],{"type":50,"value":596},{"type":44,"tag":520,"props":2260,"children":2261},{"style":544},[2262],{"type":50,"value":2263}," -fsSL",{"type":44,"tag":520,"props":2265,"children":2266},{"style":544},[2267],{"type":50,"value":2268}," https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fpublish-convex-app",{"type":44,"tag":520,"props":2270,"children":2271},{"style":544},[2272],{"type":50,"value":872},{"type":44,"tag":520,"props":2274,"children":2275},{"style":544},[2276],{"type":50,"value":2277}," publish-convex-app.mjs\n",{"type":44,"tag":520,"props":2279,"children":2280},{"class":522,"line":27},[2281,2286,2291,2296],{"type":44,"tag":520,"props":2282,"children":2283},{"style":593},[2284],{"type":50,"value":2285},"npm",{"type":44,"tag":520,"props":2287,"children":2288},{"style":544},[2289],{"type":50,"value":2290}," install",{"type":44,"tag":520,"props":2292,"children":2293},{"style":544},[2294],{"type":50,"value":2295}," -D",{"type":44,"tag":520,"props":2297,"children":2298},{"style":544},[2299],{"type":50,"value":2300}," fflate\n",{"type":44,"tag":520,"props":2302,"children":2303},{"class":522,"line":579},[2304,2308,2313],{"type":44,"tag":520,"props":2305,"children":2306},{"style":593},[2307],{"type":50,"value":685},{"type":44,"tag":520,"props":2309,"children":2310},{"style":544},[2311],{"type":50,"value":2312}," publish-convex-app.mjs",{"type":44,"tag":520,"props":2314,"children":2315},{"style":943},[2316],{"type":50,"value":2317},"            # build → zip out\u002F → moderated gateway upload\n",{"type":44,"tag":53,"props":2319,"children":2320},{},[2321,2323,2328,2330,2336,2338,2344],{"type":50,"value":2322},"It prints ",{"type":44,"tag":93,"props":2324,"children":2326},{"className":2325},[],[2327],{"type":50,"value":98},{"type":50,"value":2329}," — pass that URL to the user, and verify the\npasskey ceremony works on the published page (register a test passkey; an\nRP-ID\u002Forigin error means the three env vars above don't match the ",{"type":44,"tag":93,"props":2331,"children":2333},{"className":2332},[],[2334],{"type":50,"value":2335},".convex.app",{"type":50,"value":2337},"\nhost). If the gateway returns 403 (content moderation), it prints the reasons — a\nlegitimate app should pass; report a false positive to the user, don't evade it.\nPublishing needs a cloud Convex deployment; if anonymous\u002Flocal, ",{"type":44,"tag":93,"props":2339,"children":2341},{"className":2340},[],[2342],{"type":50,"value":2343},"npx convex dev",{"type":50,"value":2345},"\ninto a cloud project first.",{"type":44,"tag":152,"props":2347,"children":2349},{"id":2348},"step-4-stay-on-watch-with-fix_errors_automatically-start-early-dont-yield",[2350,2352,2357],{"type":50,"value":2351},"STEP 4 — stay on watch with ",{"type":44,"tag":93,"props":2353,"children":2355},{"className":2354},[],[2356],{"type":50,"value":1977},{"type":50,"value":2358}," (start EARLY, don't yield)",{"type":44,"tag":53,"props":2360,"children":2361},{},[2362,2364,2369,2371,2377,2379,2384],{"type":50,"value":2363},"This harness has no push: a user request typed into the Chef panel or a runtime\nerror sits ",{"type":44,"tag":59,"props":2365,"children":2366},{},[2367],{"type":50,"value":2368},"unseen",{"type":50,"value":2370}," until you actively look. This plugin bundles a ",{"type":44,"tag":93,"props":2372,"children":2374},{"className":2373},[],[2375],{"type":50,"value":2376},"convex-plugin",{"type":50,"value":2378},"\nMCP server with one ",{"type":44,"tag":59,"props":2380,"children":2381},{},[2382],{"type":50,"value":2383},"blocking",{"type":50,"value":2385}," tool that surfaces it as an event and fixes it.",{"type":44,"tag":53,"props":2387,"children":2388},{},[2389,2394,2396,2401,2403,2408,2410,2416],{"type":44,"tag":59,"props":2390,"children":2391},{},[2392],{"type":50,"value":2393},"Start watching as soon as the app is open (right after STEP 1) — not just after\nv1.",{"type":50,"value":2395}," The user is most engaged at the very start and will often submit a request or\nquestion while you're still building. Call ",{"type":44,"tag":93,"props":2397,"children":2399},{"className":2398},[],[2400],{"type":50,"value":1977},{"type":50,"value":2402}," between build\nmilestones and whenever you'd otherwise pause; on the FIRST call it returns\n",{"type":44,"tag":59,"props":2404,"children":2405},{},[2406],{"type":50,"value":2407},"immediately",{"type":50,"value":2409}," if anything is already pending (it surfaces existing unhandled\nrequests\u002Fquestions as ",{"type":44,"tag":93,"props":2411,"children":2413},{"className":2412},[],[2414],{"type":50,"value":2415},"existing: true",{"type":50,"value":2417},"), so feedback submitted before you started\nwatching is never lost. Then make it your standing idle action for the rest of the\nsession.",{"type":44,"tag":104,"props":2419,"children":2420},{},[2421],{"type":44,"tag":53,"props":2422,"children":2423},{},[2424,2429,2431,2436,2438,2444,2446,2452,2454,2460,2462,2468],{"type":44,"tag":59,"props":2425,"children":2426},{},[2427],{"type":50,"value":2428},"Avoid the repeated approval prompt:",{"type":50,"value":2430}," each call is a separate tool invocation,\nso a one-time \"Allow\" re-asks every loop. Choose ",{"type":44,"tag":59,"props":2432,"children":2433},{},[2434],{"type":50,"value":2435},"\"Always allow\"",{"type":50,"value":2437}," when prompted,\nor add to ",{"type":44,"tag":93,"props":2439,"children":2441},{"className":2440},[],[2442],{"type":50,"value":2443},"~\u002F.codex\u002Fconfig.toml",{"type":50,"value":2445},": ",{"type":44,"tag":93,"props":2447,"children":2449},{"className":2448},[],[2450],{"type":50,"value":2451},"[mcp_servers.convex-plugin]",{"type":50,"value":2453}," then\n",{"type":44,"tag":93,"props":2455,"children":2457},{"className":2456},[],[2458],{"type":50,"value":2459},"trust_level = \"trusted\"",{"type":50,"value":2461},". Also pass a long ",{"type":44,"tag":93,"props":2463,"children":2465},{"className":2464},[],[2466],{"type":50,"value":2467},"timeoutMs",{"type":50,"value":2469}," (e.g. 280000) so each\nblock is long and you re-call less often.",{"type":44,"tag":53,"props":2471,"children":2472},{},[2473,2475,2483,2485,2491,2493,2498,2500,2506,2508,2514],{"type":50,"value":2474},"Call the ",{"type":44,"tag":59,"props":2476,"children":2477},{},[2478],{"type":44,"tag":93,"props":2479,"children":2481},{"className":2480},[],[2482],{"type":50,"value":1977},{"type":50,"value":2484}," tool with ",{"type":44,"tag":93,"props":2486,"children":2488},{"className":2487},[],[2489],{"type":50,"value":2490},"projectDir",{"type":50,"value":2492}," set to your app's\n",{"type":44,"tag":59,"props":2494,"children":2495},{},[2496],{"type":50,"value":2497},"absolute path",{"type":50,"value":2499}," (the ",{"type":44,"tag":93,"props":2501,"children":2503},{"className":2502},[],[2504],{"type":50,"value":2505},"convex-app\u002F",{"type":50,"value":2507}," subdir, where ",{"type":44,"tag":93,"props":2509,"children":2511},{"className":2510},[],[2512],{"type":50,"value":2513},".env.local",{"type":50,"value":2515}," lives). It BLOCKS\nuntil the next event, then returns one of:",{"type":44,"tag":171,"props":2517,"children":2518},{},[2519,2537,2562],{"type":44,"tag":175,"props":2520,"children":2521},{},[2522,2528,2529,2535],{"type":44,"tag":93,"props":2523,"children":2525},{"className":2524},[],[2526],{"type":50,"value":2527},"feature_request",{"type":50,"value":1537},{"type":44,"tag":93,"props":2530,"children":2532},{"className":2531},[],[2533],{"type":50,"value":2534},"refinement_answer",{"type":50,"value":2536}," → the user wants something — handle it\n(loop back through STEP 2\u002F3), then call the tool again.",{"type":44,"tag":175,"props":2538,"children":2539},{},[2540,2546,2547,2553,2555,2560],{"type":44,"tag":93,"props":2541,"children":2543},{"className":2542},[],[2544],{"type":50,"value":2545},"convex_error",{"type":50,"value":1537},{"type":44,"tag":93,"props":2548,"children":2550},{"className":2549},[],[2551],{"type":50,"value":2552},"next_error",{"type":50,"value":2554}," → stop, read the line, fix the file, wait for\n",{"type":44,"tag":93,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":50,"value":1535},{"type":50,"value":2561}," \u002F Next to recover, then call again.",{"type":44,"tag":175,"props":2563,"children":2564},{},[2565,2571],{"type":44,"tag":93,"props":2566,"children":2568},{"className":2567},[],[2569],{"type":50,"value":2570},"quiet",{"type":50,"value":2572}," → heartbeat timeout, nothing happened — just call it again.",{"type":44,"tag":53,"props":2574,"children":2575},{},[2576,2581],{"type":44,"tag":59,"props":2577,"children":2578},{},[2579],{"type":50,"value":2580},"Loop on this tool instead of ending your turn.",{"type":50,"value":2582}," Each call blocks, so you stay on\nwatch and react within seconds — no polling, no walking away. Keep looping until the\nuser clearly says they're done.",{"type":44,"tag":152,"props":2584,"children":2586},{"id":2585},"after-the-run",[2587],{"type":50,"value":2588},"After the run",{"type":44,"tag":53,"props":2590,"children":2591},{},[2592,2594,2600],{"type":50,"value":2593},"Offer ",{"type":44,"tag":93,"props":2595,"children":2597},{"className":2596},[],[2598],{"type":50,"value":2599},"$improve-convex-plugin",{"type":50,"value":2601}," so the user can send this session for an AI review that\nimproves the quickstart.",{"type":44,"tag":152,"props":2603,"children":2605},{"id":2604},"on-failure-friction-offer-to-self-report-with-the-users-permission",[2606],{"type":50,"value":2607},"On failure \u002F friction — offer to self-report (WITH the user's permission)",{"type":44,"tag":53,"props":2609,"children":2610},{},[2611,2613,2618],{"type":50,"value":2612},"If the run doesn't go smoothly — you give up, hit a blocker, it takes way too long, or\nthe user is frustrated — don't yield silently. ",{"type":44,"tag":59,"props":2614,"children":2615},{},[2616],{"type":50,"value":2617},"Ask first, send only on a yes",{"type":50,"value":507},{"type":44,"tag":104,"props":2620,"children":2621},{},[2622],{"type":44,"tag":53,"props":2623,"children":2624},{},[2625,2627,2632],{"type":50,"value":2626},"\"That didn't go as smoothly as it should have. May I send this session — the transcript,\nwith secrets redacted — to the Convex team so they can fix what went wrong? ",{"type":44,"tag":520,"props":2628,"children":2629},{},[2630],{"type":50,"value":2631},"yes \u002F no",{"type":50,"value":541},{"type":44,"tag":171,"props":2634,"children":2635},{},[2636,2660,2670],{"type":44,"tag":175,"props":2637,"children":2638},{},[2639,2644,2646,2652,2654],{"type":44,"tag":59,"props":2640,"children":2641},{},[2642],{"type":50,"value":2643},"On yes",{"type":50,"value":2645}," → run the ",{"type":44,"tag":93,"props":2647,"children":2649},{"className":2648},[],[2650],{"type":50,"value":2651},"improve-convex-plugin",{"type":50,"value":2653}," flow (ships the redacted transcript):\n",{"type":44,"tag":93,"props":2655,"children":2657},{"className":2656},[],[2658],{"type":50,"value":2659},"curl -fsSL \"https:\u002F\u002Fbasic-anteater-667.convex.site\u002Fsend-transcript\" | QB_HARNESS=codex bash -s -- --base https:\u002F\u002Fbasic-anteater-667.convex.site --idea \"\u003Cwhat broke>\"",{"type":44,"tag":175,"props":2661,"children":2662},{},[2663,2668],{"type":44,"tag":59,"props":2664,"children":2665},{},[2666],{"type":50,"value":2667},"On no",{"type":50,"value":2669}," → respect it; send nothing.",{"type":44,"tag":175,"props":2671,"children":2672},{},[2673],{"type":50,"value":2674},"Either way, give the user an honest summary of where it got stuck.",{"type":44,"tag":53,"props":2676,"children":2677},{},[2678],{"type":50,"value":2679},"Never send the transcript without an explicit yes.",{"type":44,"tag":2681,"props":2682,"children":2683},"style",{},[2684],{"type":50,"value":2685},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2687,"total":2867},[2688,2703,2718,2733,2750,2765,2778,2788,2807,2821,2838,2852],{"slug":8,"name":8,"fn":2689,"description":2690,"org":2691,"tags":2692,"stars":2700,"repoUrl":2701,"updatedAt":2702},"guide Convex project setup and usage","Routes general Convex requests to the right project skill. Use when the user asks which Convex skill to use or gives an underspecified Convex app task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2693,2696,2697],{"name":2694,"slug":2695,"type":16},"Backend","backend",{"name":9,"slug":8,"type":16},{"name":2698,"slug":2699,"type":16},"Database","database",34,"https:\u002F\u002Fgithub.com\u002Fget-convex\u002Fagent-skills","2026-07-12T08:00:45.091281",{"slug":2704,"name":2704,"fn":2705,"description":2706,"org":2707,"tags":2708,"stars":2700,"repoUrl":2701,"updatedAt":2717},"convex-create-component","build reusable Convex components","Builds reusable Convex components with isolated tables and app-facing APIs. Use for new components, reusable backend modules, integrations, or component boundary work.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2709,2712,2715,2716],{"name":2710,"slug":2711,"type":16},"API Development","api-development",{"name":2713,"slug":2714,"type":16},"Architecture","architecture",{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},"2026-07-12T08:00:39.428577",{"slug":2719,"name":2719,"fn":2720,"description":2721,"org":2722,"tags":2723,"stars":2700,"repoUrl":2701,"updatedAt":2732},"convex-migration-helper","plan Convex schema and data migrations","Plans Convex schema and data migrations with widen-migrate-narrow and @convex-dev\u002Fmigrations. Use for breaking schema changes, backfills, table reshaping, or zero-downtime rollouts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2724,2725,2726,2729],{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},{"name":2727,"slug":2728,"type":16},"Data Engineering","data-engineering",{"name":2730,"slug":2731,"type":16},"Migration","migration","2026-07-12T08:00:51.27967",{"slug":2734,"name":2734,"fn":2735,"description":2736,"org":2737,"tags":2738,"stars":2700,"repoUrl":2701,"updatedAt":2749},"convex-performance-audit","audit Convex application performance","Audits Convex performance for reads, subscriptions, write contention, and function limits. Use for slow features, insights findings, OCC conflicts, or read amplification.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2739,2740,2743,2746],{"name":9,"slug":8,"type":16},{"name":2741,"slug":2742,"type":16},"Debugging","debugging",{"name":2744,"slug":2745,"type":16},"Monitoring","monitoring",{"name":2747,"slug":2748,"type":16},"Performance","performance","2026-07-12T08:00:50.02928",{"slug":2751,"name":2751,"fn":2752,"description":2753,"org":2754,"tags":2755,"stars":2700,"repoUrl":2701,"updatedAt":2764},"convex-quickstart","initialize Convex in applications","Creates or adds Convex to an app. Use for new Convex projects, npm create convex@latest, frontend setup, env vars, or the first npx convex dev run.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2756,2759,2760,2761],{"name":2757,"slug":2758,"type":16},"CLI","cli",{"name":9,"slug":8,"type":16},{"name":25,"slug":26,"type":16},{"name":2762,"slug":2763,"type":16},"Onboarding","onboarding","2026-07-12T08:00:43.436152",{"slug":2766,"name":2766,"fn":2767,"description":2768,"org":2769,"tags":2770,"stars":2700,"repoUrl":2701,"updatedAt":2777},"convex-setup-auth","set up authentication and access control","Sets up Convex auth, identity mapping, and access control. Use for login, auth providers, users tables, protected functions, or roles in a Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2771,2774,2775,2776],{"name":2772,"slug":2773,"type":16},"Access Control","access-control",{"name":14,"slug":15,"type":16},{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},"2026-07-12T08:00:48.652641",{"slug":2779,"name":2779,"fn":2780,"description":2781,"org":2782,"tags":2783,"stars":27,"repoUrl":28,"updatedAt":2787},"add","add capabilities to Convex applications","Add a capability to the CURRENT Convex + Next.js project — consults the served Convex capability catalog for always-current procedures (billing, crons, auth, agent, search, …); falls back to built-in hosting or @convex-dev component search. TRIGGER when the user runs $add, or asks to add hosting\u002Fpublishing or any backend capability to an existing Convex app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2784,2785,2786],{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},"2026-07-12T07:59:59.358004",{"slug":2789,"name":2789,"fn":2790,"description":2791,"org":2792,"tags":2793,"stars":27,"repoUrl":28,"updatedAt":2806},"agent","build AI agents with Convex","Build an AI agent \u002F RAG feature on Convex (@convex-dev\u002Fagent: threads, tools, vector search). TRIGGER on an AI-agent\u002Fchatbot\u002FRAG request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2794,2797,2800,2803],{"name":2795,"slug":2796,"type":16},"Agents","agents",{"name":2798,"slug":2799,"type":16},"Engineering","engineering",{"name":2801,"slug":2802,"type":16},"RAG","rag",{"name":2804,"slug":2805,"type":16},"Search","search","2026-07-12T08:00:01.921824",{"slug":15,"name":15,"fn":2808,"description":2809,"org":2810,"tags":2811,"stars":27,"repoUrl":28,"updatedAt":2820},"add authentication to Convex applications","Add sign-in (passkeys by default, OAuth\u002Fpassword optional) to the current Convex app, wired correctly incl. auth.config.ts. TRIGGER on a login\u002Fauth request for an existing app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2812,2813,2816,2817],{"name":14,"slug":15,"type":16},{"name":2814,"slug":2815,"type":16},"Authentication","authentication",{"name":9,"slug":8,"type":16},{"name":2818,"slug":2819,"type":16},"OAuth","oauth","2026-07-18T05:12:54.443056",{"slug":2822,"name":2822,"fn":2823,"description":2824,"org":2825,"tags":2826,"stars":27,"repoUrl":28,"updatedAt":2837},"billing","integrate Stripe billing in Convex apps","Add Stripe billing to a Convex app via @convex-dev\u002Fstripe (checkout + auto-verified webhook + subscription gating). TRIGGER on a payments\u002Fbilling\u002Fsubscription request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2827,2828,2831,2834],{"name":9,"slug":8,"type":16},{"name":2829,"slug":2830,"type":16},"Payments","payments",{"name":2832,"slug":2833,"type":16},"Stripe","stripe",{"name":2835,"slug":2836,"type":16},"Webhooks","webhooks","2026-07-12T08:00:08.123246",{"slug":2839,"name":2839,"fn":2840,"description":2841,"org":2842,"tags":2843,"stars":27,"repoUrl":28,"updatedAt":2851},"check-updates","upgrade Convex component versions","Check the CURRENT Convex app's pinned components against the latest recommended versions and offer to upgrade them — e.g. the passkey auth component's new email-first sign-in. TRIGGER when the user runs \u002Fcheck-updates or $check-updates, asks 'are my components up to date', 'any updates', 'upgrade auth', 'upgrade my components', or wants the newest features after a quickstart. Applies each upgrade behind a build gate (verify-or-revert) with the user's consent.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2844,2847,2848],{"name":2845,"slug":2846,"type":16},"Configuration","configuration",{"name":9,"slug":8,"type":16},{"name":2849,"slug":2850,"type":16},"Maintenance","maintenance","2026-07-12T08:00:03.236862",{"slug":2853,"name":2853,"fn":2854,"description":2855,"org":2856,"tags":2857,"stars":27,"repoUrl":28,"updatedAt":2866},"convex-authz","audit and harden Convex authorization","Audit and harden a Convex app's authorization: identity-from-arg impersonation, missing per-document ownership checks, and public queries leaking PII\u002Ffinancial data by a client-supplied id — the single largest real-defect cluster measured against generated Convex backends (44 of 214). Runs a deterministic scan for the 3 shapes, then applies the canonical requireIdentity\u002FrequireOwner pattern, then verifies with tsc. TRIGGER on 'secure my app', 'audit auth', 'add login', 'who can access this data', or an explicit 'audit my authz'. NOT always-on. SKIP when there is no convex\u002F directory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2858,2859,2862,2863],{"name":14,"slug":15,"type":16},{"name":2860,"slug":2861,"type":16},"Code Analysis","code-analysis",{"name":9,"slug":8,"type":16},{"name":2864,"slug":2865,"type":16},"Security","security","2026-07-12T08:00:04.516752",26,{"items":2869,"total":1255},[2870,2876,2883,2890,2897,2903,2910],{"slug":2779,"name":2779,"fn":2780,"description":2781,"org":2871,"tags":2872,"stars":27,"repoUrl":28,"updatedAt":2787},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2873,2874,2875],{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},{"slug":2789,"name":2789,"fn":2790,"description":2791,"org":2877,"tags":2878,"stars":27,"repoUrl":28,"updatedAt":2806},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2879,2880,2881,2882],{"name":2795,"slug":2796,"type":16},{"name":2798,"slug":2799,"type":16},{"name":2801,"slug":2802,"type":16},{"name":2804,"slug":2805,"type":16},{"slug":15,"name":15,"fn":2808,"description":2809,"org":2884,"tags":2885,"stars":27,"repoUrl":28,"updatedAt":2820},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2886,2887,2888,2889],{"name":14,"slug":15,"type":16},{"name":2814,"slug":2815,"type":16},{"name":9,"slug":8,"type":16},{"name":2818,"slug":2819,"type":16},{"slug":2822,"name":2822,"fn":2823,"description":2824,"org":2891,"tags":2892,"stars":27,"repoUrl":28,"updatedAt":2837},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2893,2894,2895,2896],{"name":9,"slug":8,"type":16},{"name":2829,"slug":2830,"type":16},{"name":2832,"slug":2833,"type":16},{"name":2835,"slug":2836,"type":16},{"slug":2839,"name":2839,"fn":2840,"description":2841,"org":2898,"tags":2899,"stars":27,"repoUrl":28,"updatedAt":2851},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2900,2901,2902],{"name":2845,"slug":2846,"type":16},{"name":9,"slug":8,"type":16},{"name":2849,"slug":2850,"type":16},{"slug":2853,"name":2853,"fn":2854,"description":2855,"org":2904,"tags":2905,"stars":27,"repoUrl":28,"updatedAt":2866},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2906,2907,2908,2909],{"name":14,"slug":15,"type":16},{"name":2860,"slug":2861,"type":16},{"name":9,"slug":8,"type":16},{"name":2864,"slug":2865,"type":16},{"slug":1711,"name":1711,"fn":2911,"description":2912,"org":2913,"tags":2914,"stars":27,"repoUrl":28,"updatedAt":2921},"develop Convex backend applications","Convex backend rules — consult this whenever writing or editing any code inside a convex\u002F directory (schemas, queries, mutations, actions, HTTP endpoints, crons, file storage, auth, component installation). TRIGGER before touching convex\u002F functions, so the code uses the object-form syntax, validators, indexes, and component patterns that generic models get wrong.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2915,2916,2917,2918],{"name":2694,"slug":2695,"type":16},{"name":9,"slug":8,"type":16},{"name":2698,"slug":2699,"type":16},{"name":2919,"slug":2920,"type":16},"TypeScript","typescript","2026-07-18T05:12:50.448833"]