Skip to content

Commit daee572

Browse files
docs(env): update agent guidance
1 parent 9543524 commit daee572

4 files changed

Lines changed: 10 additions & 9 deletions

File tree

‎packages/void/AGENTS.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ src/
9797
- **Direct activation invariant**: native Cloudflare deploy uploads a Worker Version without traffic, records the validated migration filenames in its annotation, probes that version directly, activates it at 100%, and only then synchronizes triggers. A trigger-sync failure restores the prior active version. Database migrations are forward-only; rollback warns before activating code whose recorded migration set is older or unknown.
9898
- **Direct Sandbox entitlement invariant**: `void/sandbox` is opt-in and is the only public Void feature that currently requires Workers Paid on the native Cloudflare path. When source inference or `void.json` enables it, deploy must verify Containers with a read-only account probe after authentication and before provisioning/building, then explain both the Workers Paid signup and Containers/Cloudchamber token permissions on failure. A non-Sandbox app must emit no Container and perform no Containers probe.
9999
- **Migration DB path**: Miniflare stores D1 data at a deterministic path computed from the `database_id` using HMAC-SHA256. The `getMiniflareDatabasePath()` function in `migrations/runner.ts` replicates this algorithm so migrations target `<persist-root>/v3/d1/miniflare-D1DatabaseObject/<hash>.sqlite` (for example `.void/v3/...` in default/class-A mode and `.wrangler/state/v3/...` in class-B/C framework mode).
100-
- **Drizzle-first database**: Schema is defined in `db/schema.ts` (Drizzle table definitions). `void/db` exports a dialect-aware Drizzle instance for D1, PostgreSQL, or MySQL. `@schema` is an auto-configured alias for `db/schema.ts`. Migrations live in `db/migrations/`. CLI commands: `void db push` (prototype), `void db generate` (create migration files), `void db migrate` (apply locally). When auth is enabled, `void db generate` runs codegen in production mode and adds `.void/better-auth-schema.ts` to Drizzle Kit's schema inputs. Direct Cloudflare deploy applies PostgreSQL or MySQL migrations from the shell-provided production `DATABASE_URL`; PostgreSQL is transactional, while MySQL DDL is not. `drizzle-orm` and `drizzle-kit` ship with void.
101-
- **Database provisioning adapters**: `void db connect <url>` saves an external database URL to `.env.local` and syncs a linked Void project; `--local-only` skips the sync. `void db connect --provider neon` provisions through the built-in Neon adapter using `NEON_API_KEY`. Third-party packages or local modules can export a `DatabaseProviderAdapter` built with `void/database-provider`; runtime database code remains provider-neutral.
100+
- **Drizzle-first database**: Schema is defined in `db/schema.ts` (Drizzle table definitions). `void/db` exports a dialect-aware Drizzle instance for D1, PostgreSQL, or MySQL. `@schema` is an auto-configured alias for `db/schema.ts`. Migrations live in `db/migrations/`. CLI commands: `void db push` (prototype), `void db generate` (create migration files), `void db migrate` (apply locally). When auth is enabled, `void db generate` adds `.void/better-auth-schema.ts` to Drizzle Kit's schema inputs. Direct Cloudflare deploy applies PostgreSQL or MySQL migrations from the shell-provided production `DATABASE_URL`; PostgreSQL is transactional, while MySQL DDL is not. `drizzle-orm` and `drizzle-kit` ship with void.
101+
- **Database provisioning adapters**: `void db connect <url>` saves an external database URL to `.env` and syncs a linked Void project; `--local-only` skips the sync. `void db connect --provider neon` provisions through the built-in Neon adapter using `NEON_API_KEY`. Third-party packages or local modules can export a `DatabaseProviderAdapter` built with `void/database-provider`; runtime database code remains provider-neutral.
102+
- **Environment model**: `env.ts` is the checked-in schema; root `.env` is the only dotenv file and is local-only. Production server keys use the remote secret store, while fixed-prefix `VITE_*` keys are public build-time values. Never add `.env.*` precedence, `.secret()`/`.public()` modifiers, or plaintext Worker vars for schema-declared server keys.
102103
- **Typed Durable State convention**: each default-exported `defineDurableState()` definition in `durable-objects/*.ts` becomes a filename-derived binding and worker class (`shopping-cart.ts` → `SHOPPING_CART` / `ShoppingCartDurableObject`). The generated entry calls the internal `__bind()` hook so named imports can use `State.get(name)` without touching `c.env`, exports `State.class`, and emits a stable `new_sqlite_classes` migration. `syncWranglerDurableObjects()` persists bindings and append-only class migration history in `wrangler.jsonc`; never regenerate migration order solely from the current sorted files. Runtime operations are serialized and persisted after successful typed RPC, `fetch`, or `alarm` handlers; versioned value migrations run on load. This is native-Void + Cloudflare only and is supported by direct Cloudflare deploys, unlike legacy KV-backed `*.ws.ts` classes.
103104
- **Journal coherence invariant**: `db/migrations/*.sql` and `db/migrations/meta/_journal.json` must stay in sync — every `.sql` file has a matching journal entry (by `tag`) and vice versa. `assertJournalCoherence` in `src/migrations/validate.ts` is the gate, called from `deploy`, `db status`, `db migrate`, and `db reset`. The two CLI commands that mutate migration state — `void gen migration` and `void db rename-migrations` — are responsible for keeping the journal coherent themselves: the first appends a new entry when writing a file (failing loud if the journal is missing — run `drizzle-kit generate` first), the second rewrites `tag` values alongside the file renames and also renames the matching `meta/<prefix>_snapshot.json` (with byte-level rollback on failure). `gen migration` additionally copies the previous `meta/<idx:04d>_snapshot.json` forward to the new idx so drizzle-kit's drop/rollback tooling keeps working on mixed hand-written + drizzle projects; projects without prior snapshots are skipped silently. Drift will fail loudly before touching any remote DB. Motivated by [void-sdk/void#6](https://github.com/void-sdk/void/issues/6), where an orphan scaffolded `.sql` file half-applied against D1 and wedged the deploy.
104105

‎packages/void/AGENT_PROMPT.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Database dialects: omit `database` for D1, use `"database": "pg"` for PostgreSQL
88

99
Durable state: create `durable-objects/name.ts`, named- and default-export the same `defineDurableState()` value from `void/durable`, and call typed RPC methods through `State.get(id)`. Void derives the binding, worker class, and SQLite-backed Cloudflare migration from the filename. This supports native Void apps on Cloudflare, including direct Cloudflare deploys, and is separate from legacy `*.ws.ts` routes.
1010

11-
External database setup: use `void db connect <connection-string>` to update `.env.local` and a linked Void project, or `NEON_API_KEY=... void db connect --provider neon` to provision Neon. Pass `--local-only` to avoid remote sync. Custom provider modules export a `DatabaseProviderAdapter` from `void/database-provider`.
11+
External database setup: use `void db connect <connection-string>` to update `.env` and a linked Void project, or `NEON_API_KEY=... void db connect --provider neon` to provision Neon. Pass `--local-only` to avoid remote sync. Custom provider modules export a `DatabaseProviderAdapter` from `void/database-provider`.
1212

13-
Env: declare every env key in `env.ts` at the project root via `defineEnv({ KEY: string(), ... })` from `void/env`. Read values via `import { env } from "void/env"`. Schema validation runs at dev start (warns) and on `void deploy` (hard error on missing prod secrets). Use `VITE_*` prefix for keys that should be exposed to client code.
13+
Env: declare every env key in `env.ts` at the project root via `defineEnv({ KEY: string(), ... })` from `void/env`. Read values via `import { env } from "void/env"`. Use only root `.env` for local development; it is never deployed. Every non-client production key belongs in the remote secret store. Use the fixed `VITE_*` prefix only for public values embedded at build time.
1414

1515
CI/editor prep: run `void prepare` to generate `.void/routes.d.ts`, `.void/db.d.ts`, `.void/queues.d.ts`, `.void/env.d.ts`, and `.void/tsconfig.json` without booting Vite. Run it after `npm install` in CI or a fresh clone before typechecking; `vite dev` and `vite build` regenerate these during normal workflows.
1616

@@ -20,6 +20,6 @@ Logs: surface app-level errors that should show up under `void project logs --le
2020

2121
Requests: `void project logs` only has rows when a worker actually ran. 5xx generated by the edge router, and every request to a static/SPA project, produce no log line at all. Use `void project requests --status 5xx --range 12h` to see those — it lists status, method, and duration for every request the edge served, whether or not a worker was invoked.
2222

23-
Deploy platform: `void init` asks for Cloudflare (default), Void, or Skip and saves `platform` in `.void/project.json`. Choosing Cloudflare creates or augments `wrangler.jsonc`, offers Wrangler login, and saves the selected `account_id`; choosing Void can handle Void auth and project linking. `void deploy` uses the saved choice; `--platform cloudflare` and `--platform void` override it without changing project config, while the legacy `--backend cloudflare` alias remains supported. The Cloudflare path supports full Void Workers; static sites, SPAs, known SSGs, and `--dir`; fully prerenderable `output: "static"` Pages apps; and Cloudflare builds from TanStack Start, React Router, vinext App Router and Pages Router, SvelteKit, Nuxt, Analog, and Astro. Hybrid/SSR apps retain their application Worker; static assets run behind a thin shared edge Worker. Worker apps automatically create or adopt D1/KV/R2/Queues/Hyperdrive resources and configure inferred typed-state and WebSocket classes as SQLite Durable Objects. Custom D1 migration directories, tables, and patterns are accepted only when Wrangler's exact file set and numeric order match the migrations Void validated. Keys marked `.secret()` in `env.ts` become encrypted Worker secrets; auth-enabled deploys preserve or create a persistent encrypted `BETTER_AUTH_SECRET`. PostgreSQL/MySQL provisioning and migrations read `DATABASE_URL` only from the deploy shell. Direct deploy uploads an immutable Worker Version, probes it, activates it at 100%, synchronizes triggers, and restores the previous version if readiness or trigger sync fails. Durable Object versions without preview URLs are staged at 0% and probed with a workers.dev version override; the same safe fallback applies when Access blocks a generated preview alias but admits the stable Worker hostname. Set `CLOUDFLARE_WORKERS_SUBDOMAIN` in fresh CI, while local deploys cache it automatically. If Cloudflare Access protects the Worker's `workers.dev` hostname, supply an admitted `CF_ACCESS_CLIENT_ID` / `CF_ACCESS_CLIENT_SECRET` service-token pair for CI or a short-lived `CF_ACCESS_TOKEN` from `cloudflared` locally. Saved Cloudflare targets make `void secret`, `void domain`, `void project status|logs|rollback`, and remote `void db` commands operate directly; logs are live tailing. Rollback restores the selected version's saved schedules, queues, workflows, routes, and domains but never reverses database migrations; legacy versions without trigger snapshots are rejected. Direct commands target the root top-level Wrangler config only; named environments, worker-bearing `--skip-build`, and node/bun/deno deploy targets fail closed. Avoid concurrent first deploys from different hosts because provisioning locks only the local config path.
23+
Deploy platform: `void init` asks for Cloudflare (default), Void, or Skip and saves `platform` in `.void/project.json`. Choosing Cloudflare creates or augments `wrangler.jsonc`, offers Wrangler login, and saves the selected `account_id`; choosing Void can handle Void auth and project linking. `void deploy` uses the saved choice; `--platform cloudflare` and `--platform void` override it without changing project config, while the legacy `--backend cloudflare` alias remains supported. The Cloudflare path supports full Void Workers; static sites, SPAs, known SSGs, and `--dir`; fully prerenderable `output: "static"` Pages apps; and Cloudflare builds from TanStack Start, React Router, vinext App Router and Pages Router, SvelteKit, Nuxt, Analog, and Astro. Hybrid/SSR apps retain their application Worker; static assets run behind a thin shared edge Worker. Worker apps automatically create or adopt D1/KV/R2/Queues/Hyperdrive resources and configure inferred typed-state and WebSocket classes as SQLite Durable Objects. Custom D1 migration directories, tables, and patterns are accepted only when Wrangler's exact file set and numeric order match the migrations Void validated. `.env` is local-only; schema-declared server values use remote secret storage, required names are emitted through `secrets.required`, and plaintext Worker vars with those names are rejected. Auth-enabled deploys preserve or create a persistent encrypted `BETTER_AUTH_SECRET`. PostgreSQL/MySQL provisioning and migrations read `DATABASE_URL` only from the deploy shell. Direct deploy uploads an immutable Worker Version, probes it, activates it at 100%, synchronizes triggers, and restores the previous version if readiness or trigger sync fails. Durable Object versions without preview URLs are staged at 0% and probed with a workers.dev version override; the same safe fallback applies when Access blocks a generated preview alias but admits the stable Worker hostname. Set `CLOUDFLARE_WORKERS_SUBDOMAIN` in fresh CI, while local deploys cache it automatically. If Cloudflare Access protects the Worker's `workers.dev` hostname, supply an admitted `CF_ACCESS_CLIENT_ID` / `CF_ACCESS_CLIENT_SECRET` service-token pair for CI or a short-lived `CF_ACCESS_TOKEN` from `cloudflared` locally. Saved Cloudflare targets make `void secret`, `void domain`, `void project status|logs|rollback`, and remote `void db` commands operate directly; logs are live tailing. Rollback restores the selected version's saved schedules, queues, workflows, routes, and domains but never reverses database migrations; legacy versions without trigger snapshots are rejected. Direct commands target the root top-level Wrangler config only; named environments, worker-bearing `--skip-build`, and node/bun/deno deploy targets fail closed. Avoid concurrent first deploys from different hosts because provisioning locks only the local config path.
2424

2525
Full docs are in `node_modules/void/docs/`. If you have the `void` skill available, use it for a complete API reference covering project structure, routing, pages mode, database, auth, typed fetch, KV, storage, queues, cron jobs, CLI, configuration, and deployment.

0 commit comments

Comments
 (0)