- TypeScript 93.1%
- CSS 6.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .alchemy/log | ||
| .wrangler | ||
| public | ||
| server | ||
| .gitignore | ||
| AGENTS.md | ||
| alchemy.run.ts | ||
| CLAUDE.md | ||
| monitor.config.ts | ||
| nitro.config.ts | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.json | ||
Virgil
Virgil runs as a Nitro v3 application on Cloudflare Workers. Alchemy provisions the Worker and its Cloudflare KV namespace.
How the pieces fit together
Alchemy owns the infrastructure lifecycle:
Cloudflare.KV.Namespace("KV")provisions a KV namespace.Command.Buildruns Nitro's Cloudflare-module build.Cloudflare.Workeruploads Nitro's prebuilt Worker output.- The Worker receives the namespace as the
VIRGIL_KVbinding.
Nitro mounts that binding through unstorage:
storage: {
kv: {
driver: "cloudflare-kv-binding",
binding: "VIRGIL_KV",
},
},
Application code only depends on Nitro's storage API:
import { useStorage } from "nitro/storage";
const kv = useStorage("kv");
await kv.setItem("domains", ["example.com"]);
const domains = await kv.getItem<string[]>("domains");
pnpm dev:nitro uses the filesystem-backed devStorage mount at
.data/kv. pnpm dev runs Alchemy's local Cloudflare environment, where the
same mount is backed by an emulated KV binding.
Local development
pnpm install
pnpm dev
Use the local Nitro server without Alchemy when Cloudflare emulation is not needed:
pnpm dev:nitro
Plan and deploy
Set the Discord webhook used by the checker task:
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
Alchemy deploys this value as a Cloudflare secret binding. The domain monitor
runs every day at 00:00 UTC and keeps each domain in KV after it expires. It
stores the RDAP expiry date and sends one-time notifications at 30, 14, 7, 3,
and 1 day before expiry, when the domain expires, and when RDAP reports it as
available. If a domain is renewed, the notification schedule resets for its
new expiry date.
Authenticate with Alchemy when prompted, then inspect the plan before applying it:
pnpm plan
pnpm deploy
Use the project-local Alchemy binary through these scripts or with
pnpm exec alchemy. Do not use pnpm dlx alchemy: it downloads a separate
version instead of using the version pinned in this project.