Imported from zohaibakber/store (
AGENTS.md). Install upstream withnpx skills add zohaibakber/store. Copyright stays with the author.
Using Vite+, the Unified Toolchain for the Web
This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called vp. Vite+ is distinct from Vite, and it invokes Vite through vp dev and vp build. Run vp help to print a list of commands and vp <command> --help for information about a specific command.
Docs are local at node_modules/vite-plus/docs or online at https://viteplus.dev/guide/.
Built-in Commands vs Scripts
vp <name> runs a built-in command. vp run <name> runs a package.json script or a vite.config.ts task. Scripts cannot overwrite built-ins, so vp dev and vp run dev may do different things. Check package.json and vite.config.ts first, and run vp run <name> when the project defines a script or task with that name.
Tool Versions
Run vp toolchain to show versions and relationships in the active Vite+
release. Add a tool name to select part of the graph. For example, run
vp toolchain vite. Use --global to ignore the local vite-plus package. Use
vp why <package> to show the package-manager dependency graph.
Review Checklist
- Run
vp installafter pulling remote changes and before getting started. - Run
vp checkandvp testto format, lint, type check and test changes. - Check if there are
vite.config.tstasks orpackage.jsonscripts necessary for validation, run viavp run <script>. - If setup, runtime, or package-manager behavior looks wrong, run
vp env doctorand include its output when asking for help.
Typography
These rules apply to all UI work in apps/web. The tokens live in
apps/web/src/styles.css (Tailwind v4 @theme block).
Conventions, not hard clamps: @theme sets the font family, but nothing blocks
other weights or sizes. Follow the rules anyway.
- Font. Inter (
"Inter Variable", loaded via@fontsource-variable/inter). JetBrains Mono ("JetBrains Mono Variable", loaded via@fontsource-variable/jetbrains-mono) is for code only. - Weights. Regular (400) and medium (500) only. Medium is the maximum.
Avoid
font-semiboldandfont-bold. Nothing prevents them, so a few uses have crept in; don't add more. - Font sizes. 12px and 14px are the base sizes (body text is 14px, small
text is 12px). The scale is 12 / 14 / 16 / 18 / 24. Use Tailwind utilities:
text-xs(12),text-sm(14, body default),text-base(16),text-lg(18),text-2xl(24). Avoidtext-xlandtext-3xl+ and don't introduce new sizes. - Icons. Hugeicons, via
<HugeiconsIcon icon={...} />from@hugeicons/reactwith icons from@hugeicons/core-free-icons.
UI components
apps/web/src/components/ui is a registry managed by components.json, not
application code. Primitives there may have no importer yet. That is inventory,
not dead code, so don't delete them for being unused.
Cursor Cloud instructions
Toolchain (pnpm 11.22.0 + Node.js 24 + the Vite+ vp CLI) is installed in the VM and on
PATH in login shells. The startup update script runs vp install and fetches
the Electron binary. From the repo root: vp install, vp check, vp test,
and vp build (Turborepo fans them out per package).
- Electron binary. If installation leaves
apps/desktop/node_modules/electronwithout itsdist/binary, orvp devfor the desktop errors that Electron is missing, runnode apps/desktop/node_modules/electron/install.js. - Desktop app.
vp run dev:desktopfrom the repo root starts the API/auth workers and the web renderer, thenapps/desktop'sdevscript waits for:5174and packs main/preload withvp pack --watch. Unpackaged/dev keeps an escape hatch:ELECTRON_DISABLE_SANDBOX=1(the SUIDchrome-sandboxhelper can't run) andDISPLAY=:1in the headless VM. Production packages flip Electron Fuses in electron-builder'safterPackhook and keepsandbox: true.ERROR:dbus/...lines in the log are harmless. Package withvp run --filter @store/desktop build(orrelease). Do not setnodeLinker: hoisted— that duplicates React across packages. - Backend.
apps/serverruns viapnpm exec alchemy dev --stage dev --env-file .env.devon port:8787. Alchemy stores state remotely and binds real dev-stage D1, Hyperdrive, and Postgres. There is no local emulation. It fails fast withoutCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID, and needs a.env.devwith the auth JWT key pair, refresh and ephemeral peppers, and Google OAuth credentials. Use different secrets per stage. Do not commit env files or env templates. - Auth gating. The desktop renderer and the hosted SPA are gated behind
sign-in/sign-up, which call the backend API. End-to-end auth UI (sign up,
create organization, sync) needs the backend running with the credentials
above. Inventory authority is
Postgres. PowerSync streams organization-scoped rows into renderer SQLite
(
@store/client-db). D1 is auth. There is no organization Durable Object and no/api/sync/livepath. Inventory can be driven from the local PowerSync replica without the backend.
