agentleFS
yamcodesyamcodes/arkenv/AGENTS.md

arkenv

AGENTS.md147 starsChanged 23 days agoMITView on GitHub

ArkEnv is a Nub + Turborepo monorepo for a TypeScript env-var validation library. Nub is the package manager (packageManager: nub@…, lockfile nub.lock, isolated .store via nub.jsonc) as well as the script runner — do not mix pnpm install into the same tree. There are no databases or external services; the product long-running process is the www docs site (Next.js). apps/dash is an optional maintainer dashboard and is not started by nub run dev / nub run www. Standard commands live…

  • Reads credentials

We split this AGENTS.md into the rules it gives an agent

4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Prefer Nub (nub run, nubx, nub install, nub / nub watch, nub node).

    line 19
  2. Very specific:

    Run docs site (dev): nub run www (serves on http://localhost:3000)

    line 23
  3. Distinctive:

    Use the full phrase "environment variables" in headings and SEO-facing copy.

    line 43
  4. Distinctive:

    Do not claim "zero dependencies" without "runtime" unless talking only about core/standard.

    line 47

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Cursor Cloud specific instructions

ArkEnv is a Nub + Turborepo monorepo for a TypeScript env-var validation library. Nub is the package manager (packageManager: nub@…, lockfile nub.lock, isolated .store via nub.jsonc) as well as the script runner — do not mix pnpm install into the same tree. There are no databases or external services; the product long-running process is the www docs site (Next.js). apps/dash is an optional maintainer dashboard and is not started by nub run dev / nub run www. Standard commands live in package.json, docs/CONTRIBUTING.md, and docs/TESTING.md — prefer those.

This is the v1 branch. Its package layout differs from dev (v0): here packages/arkenv is the CLI (published as arkenv) and the core runtime lives in packages/core (published as @arkenv/core). There is no packages/cli on v1. v1 publishes pre-release versions (1.0.0-alpha.x) under the alpha npm tag.

Services / apps

  • packages/* — the publishable library packages: arkenv (the CLI, in packages/arkenv/), @arkenv/core (core runtime, in packages/core/), @arkenv/standard (in packages/standard/), plus @arkenv/nextjs, @arkenv/nuxt, @arkenv/vite-plugin, @arkenv/bun-plugin, @arkenv/build, @arkenv/agent-plugin, and @arkenv/fumadocs-ui (which live in the nextjs/, nuxt/, vite-plugin/, bun-plugin/, build/, agent-plugin/, and fumadocs-ui/ directories), plus internal helpers under packages/internal/*. These are the core product.
  • apps/www — the documentation website (Next.js 16 + Fumadocs). This is the product app.
  • apps/dash — optional maintainer Dashfy dashboard (GitHub + npm). Not in CI. Run with nub run dash (Vite on http://localhost:3001, Dashfy server on http://127.0.0.1:5001). Copy apps/dash/.env.example to apps/dash/.env first.
  • apps/playwright-www — Playwright e2e suite targeting www.
  • apps/playgrounds/* and examples/* — framework sandboxes / fixtures (optional).

Common commands (run from repo root)

Prefer Nub (nub run, nubx, nub install, nub / nub watch, nub node). It replaces tsx / ts-node / tsconfig-paths / dotenv, pnpm run, npx / pnpm exec, pnpm install, and nvm.

  • Install deps: nub install
  • Build everything: nub run build · packages only: nub run build:packages
  • Run docs site (dev): nub run www (serves on http://localhost:3000)
  • Maintainer dashboard: nub run dash (Vite on http://localhost:3001; copy apps/dash/.env.example to apps/dash/.env first)
  • Lint/format + workspace validation: nub run check
  • Typecheck: nub run typecheck
  • Unit/integration tests: nub run test -- --run (Vitest)
  • E2E: see caveat below.

Non-obvious caveats

  • Changesets / @manypkg do not understand Nub identity. scripts/ensure-manypkg-workspace.js materializes a gitignored packages-only pnpm-workspace.yaml from package.json → workspaces.packages (postinstall, nub run check / changeset / release, and the Release workflow) so Changesets can discover packages. Do not commit that file or run pnpm install because of it. Release publish does not use pnpm: scripts/changeset-publish.js rewrites workspace: / catalog: to concrete versions, forces Changesets onto the npm publish tool, then runs changeset publish (avoids Nub’s broken lockfile-less pnpm@latest stub).
  • Pending changesets are only .changeset/<name>.md. Never write new ones under .changeset/pre/ — that directory is the consumed archive filled by changeset version / Version Packages while v1 is in pre mode. Files that only exist in pre/ are skipped by release planning and will not version (when nothing else is pending, changesets/action logs “No changesets found”). See the changeset skill and .agents/AGENTS.md §6.
  • Bun is required for @arkenv/bun-plugin and some bun playground/example flows, and CI installs Bun 1.3.13. It is installed globally at ~/.bun/bin (on PATH via ~/.bashrc for login shells); if a session's shell can't find bun, run export PATH="$HOME/.bun/bin:$PATH". Bun is not needed for the core build / nub run test / running www.
  • Node 24.21.0 is pinned in .node-version (exact patch, committed). CI default jobs read that file; do not hardcode 24 in workflows. Latest-channel jobs pass node-version: 26 so they rewrite the pin for that job only (nub run still follows .node-version; see nubjs/setup-nub#12). Playground/example engines.node is >=22, except SolidStart (>=24). tsdown warns on Node < 22.18. Prefer nub node over nvm. Bare ni/n still use PATH Node if it is not the Nub shim.
  • E2E must be run the CI way (against a production server), not against nub run www. The Playwright config uses next start when CI is set and next dev otherwise; the dev server emits console errors that the smoke test forbids and can be overwhelmed by parallel workers (ERR_CONNECTION_REFUSED). Build www first (nub run build --filter=www...), then run e.g. CI=1 nubx playwright test --project=chromium from apps/playwright-www. Playwright browsers must be installed once per VM: nubx playwright install --with-deps chromium firefox (webkit is macOS-only).
  • The CLI tests print fatal: not a git repository / Using 'master' as the name... git hints while running — this is expected (they scaffold temp git repos) and does not indicate failure.
  • To run a package that consumes the local (workspace) build, use a workspace playground (e.g. apps/playgrounds/node, which depends on @arkenv/core: workspace:*). Copy .env.example to .env first, then nub run start (scripts use Nub to run TypeScript and load .env). The examples/* projects are standalone npm projects that resolve the published packages (e.g. @arkenv/core) from npm, not the local build.

Learned User Preferences

  • Spell public copy as "Typesafe" (one word), not "Type-safe".
  • Use the full phrase "environment variables" in headings and SEO-facing copy; "env vars" is fine in subheads and body.
  • Match docs voice to turborepo.dev plus the existing getting-started and root docs (index, support policy, community).
  • Match homepage hero typography to turborepo.dev (heading size, weight, and text style).
  • Nub (https://nubjs.com/) is a real Node toolkit the user likes; never treat "Nub" as a typo for Bun. Prefer it over tsx / ts-node / tsconfig-paths / dotenv, pnpm run, npx / pnpm exec, pnpm install, and nvm in this repo (scripts, CI, CONTRIBUTING, AGENTS) and in examples/ / apps/playgrounds/. User-facing docs keep stock defaults selected (npx / node --env-file / tsx) and author package-install fences in npm form; the tabs also offer Nub (nubx / nub add). Do not replace npm-form fences with Nub-only copy except on the dedicated Using ArkEnv with Nub guide.
  • Do not claim "zero dependencies" without "runtime" unless talking only about core/standard.

Learned Workspace Facts

  • Site Nav is a full-bleed wireframe header (row 0 of the hairline grid): no floating pill, no side inset, border-bottom in --color-rule. Get started / search / nav-link hover / search dialog overlay (.arkenv-search-dialog) use 0.375rem radius (--radius-control / --site-nav-radius), not rounded-full. Nav labels are medium, not semibold: wordmark / Get started / Search font-weight: 500; Docs / Playground / Roadmap 450; mobile menu links stay 400, drawer Get started 500. Hero install command and code windows use the same 0.375rem (--radius-frame on editor chrome). The announcement chip is the exception: fully round (--radius-pill). Docs share that same Row 0. Docs are not a bento: Vite four-rail cage in --color-rule-y (--color-fd-border aliases it; slightly softer than horizontal --color-rule) — #nd-sidebar and #nd-toc each have border-inline-start and border-inline-end. Inner splitters (sidebar end, TOC start) stop at the site footer; outer rails (sidebar start, TOC end) continue through .site-footer-bleed via .docs-outer-rails — a centered min(100%, var(--fd-layout-width)) column with the same border-inline-start/end as the cage (not background-position %, which sits ~1px left of the borders) so they cross the edge-to-edge footer-top hairline down to the bottom of the page. The copyright bar hairline (.home-aurora__footer-meta) is edge-to-edge like the homepage (100cqi / 50% - 50cqi). Docs and home share SiteFooter (docs passes rails so the bleed + outer cage wrap the same footer). MIT License → https://github.com/yamcodes/arkenv/blob/v1/LICENSE; Yam Borodetsky → https://yam.codes. Copyright bar uses homepage padding-block (--sf-space-sm); no extra pad below the meta. The TOC spy is a 2px ink bar at inset-inline-start: -1px on the article↔TOC splitter (no inner TOC line). The Give feedback hairline (data-docs-toc-footer) spans rail-to-rail; --docs-toc-gutter pads the title/list/footer, not the column. The article pager hairline ([data-docs-footer] border-top) spans the sidebar inner rail to the TOC inner rail; --docs-page-gutter pads the Previous/Next links. Sidebar active-pill left edge lines up with the Site Nav wordmark icon (cyan helm); equal --site-nav-gutter column pads inset the pill the same from both sidebar rails; items use px-2.5 inner pad so glyphs clear the 0.25rem radius. The outer sidebar rail stays. Sidebar active pills and the “Enjoying ArkEnv?” card use 0.25rem radius; Copy page uses 0.375rem (--docs-control-radius), same as Get started / Search. Docs have no hero spotlight or 24px dot field — #docs-chrome-shell and the mobile drawer are paper (the homepage hero keeps its atmosphere). #nd-page is solid paper so the reading column stays open.
  • Homepage TypeScript snippets (hero, 04 Modular ArkType / Zod / Valibot) use the same Twoslash highlighter as the docs (highlightTwoslash + HeroTwoslashHtml). The 01 IDE autocomplete mock, 02 dark terminal dump, and 03 browser overlay are not Twoslash. Pitch sections have no numbered kickers and no zig-zag. Sections 1–4 sit in a Vite-style seamless bento: 2×2 for the four mechanics. Copy packs from the top; widgets hug their content and margin-top: auto so they bleed to the cell’s bottom hairline (no cell bottom pad, square window corners, no window bottom border). Leftover cell height is paper above the window, not empty dark inside it. At ≥64rem the 2×2 is two flex columns — do not subgrid heading/widget tracks. 2×2 body copy is 70% of the half-cell (not a 26rem cap). Hairline grid uses --color-rule (horizontals) and --color-rule-y (long vertical rails, slightly softer) with no gaps; both are dimmer than the old undifferentiated oklch(30% 0.02 200) rule; --rule-hair stays 1px; short interior verticals (trust-bar inset, install-pill divider) use --color-rule so they read on paper-2; vertical rails stay on the content column from 960px, with the docs sidebar (below that there are no side lines and no rail margin; copy keeps one gutter) while horizontals, hatch stripes, paper bands (trust + footer), and the footer-top rule run edge-to-edge (open-slide). Hero, trust, footer, and 2×2 copy share one content inset (--home-rail-inset + --home-gutter); pitch cells pad inline with --home-gutter, not --space-lg. Grid intersections are bare crossings — no carets, notches, plus ticks, or ArkEnv marks. Headings: “Fail-fast at startup” · “Strictly typed” · “Full-stack ready” · “Bring your own validator”. Then outro. Nav Playground is the StackBlitz example (external), not an in-page #demo. Section 1 is a dark terminal (home-aurora__tty) docked to the cell bottom — a normal contained window (not a clipped peek): $ npm run dev (cyan $ matching the hero install pill via --color-accent), blank line, then the real ArkEnvError dump (Errors found while validating environment variables in --color-danger / ANSI 31; ArkEnvError: stays unstyled ink-2). Issue lines indent 2 spaces: keys in --color-cmd (ANSI 33 yellow), (was …) values in --color-accent (ANSI 36 cyan) — DATABASE_URL must be a URL string (was [REDACTED]) and PORT must be a number (was a string). No Invalid environment variables, no validating environment... filler, no info - loaded env from .env (ArkEnv is not a dotenv loader), no >_, no ready/server-started line, no stack, no Node internals, no Copy. Section 2 is a dark VS Code mock (import { env } from "./env"; / const db = env.| / const port = env.PORT;) docked to the cell bottom; editor body top pad is --space-2xs so the snippet sits on the chrome, not in a well. IntelliSense (DATABASE_URL as a string) hangs off the caret on env.| over the following const port line inside min pane pad (padding-block-end: 6.5rem) — inside the code window, not clipped at the cell hairline. The editor pre stays overflow: visible so overflow-x: auto cannot compute as overflow-y: auto and clip the popup. Not a light editor. No dummy blank lines to equalize card heights. No before/after ./env.ts wall — that tutorial belongs in docs under “Why ArkEnv?”. Section 3 is a browser window (home-aurora__browser: traffic lights + localhost:3000 omnibox) with a Next.js Runtime Error overlay (home-aurora__fail): red Runtime Error badge, the message Do not access server-only key 'DATABASE_URL' on the client since it will leak sensitive data (prevented by ArkEnv), a grey Next.js source bar (TS app/components/header.tsx (5:12) @ Header), and a one-line code-frame of the leak (env.DATABASE_URL). No Call Stack, no schema behind it, no Copy (the overlay is not a snippet). Chrome + overlay hug (grid-template-rows: auto auto, no inner 1fr / flex-grow spacer). Leftover cell height is paper above the window (margin-block-start: auto on the visual), not empty dark inside it. Section 4 is one mixed ./env.ts via @arkenv/core, a normal full-width code window like the hero example and Strictly typed (not a clipped/peek crop; no bento overflow-x: clip / overflow-wrap: anywhere on the snippet): visible snippet starts at export const env (imports sit above twoslash ---cut---). ArkType DSL (NODE_ENV), Valibot v.pipe(v.string(), v.url()) (DATABASE_URL — v.url() is an action, not a schema), Zod z.boolean() (DEBUG) — no type() wrap, no z.coerce, no LOG_LEVEL/PORT, no validator tabs (the hero example is the only tab bar). Homepage tabs are hero-only (ArkType / Zod) on the sliding-ink tablist. Code windows share home-aurora__code-window (filename chrome uses the same --color-paper-2 as the snippet body — no two-tone header) and the docs CodeBlockCopyButton (accessible name “Copy”) on the filename chrome — hero copies the visible ArkType/Zod tab; pitch code windows (Strictly typed, Bring your own validator) copy their raw source. The fail-fast terminal is a TTY dump without Copy. The Full-stack ready overlay has no Copy. Inline links match the footer: ink-2, hover to ink, no underline. Section 3 leak highlight uses home-aurora__fail; section 1’s terminal is home-aurora__tty (real dump, not an overlay chip). Hero example tabs are ArkType / Zod only; Modular is one mixed snippet (starts at export const env; ArkType DSL NODE_ENV, Valibot URL pipe DATABASE_URL, Zod boolean DEBUG — no type(), no z.coerce, no numeric Valibot). "Typesafe environment variables" / "with [cycling name]" on one line (ArkType, Zod, Valibot) — glued with a non-breaking space so “with” and the name stay on one line without jump or overflow. That cycle is independent of the example tabs (ArkType / Zod only) and pauses only while the pointer is over the cycling name (.home-aurora__cycle), not the rest of the headline or the example. Dwell is 3s; the name slide is 375ms cubic-bezier(0.16, 1, 0.3, 1). Reduced motion locks to ArkType. The example window is vanilla ./env.ts only — no Vanilla/Vite/Next.js switcher. Hero atmosphere is a 2.5% white spotlight plus the dot field — no teal radial blooms. The 2×2 bento sits on the same flat --color-paper as the hero (not dark-gray cards); trust and footer stay paper-2 bands. The hero trust bar is one band (Colin’s quote + “Works with” marquee). At ≥64rem a short inset hairline sits in the gap between them — --home-gutter from “Creator of Zod” and the same --home-gutter before “Works with” (matching avatar↔left rail). Paint it --color-rule (not --color-rule-y) so it reads on the paper-2 band. It must not meet the band’s top/bottom rules. Open-slide-style hatch stripes break the bento between grid→outro (not after the trust bar — too soon). Both hero tabs use the same keys (DATABASE_URL, PORT, CI); ArkType PORT is "0 <= number.integer <= 65535 = 3000" (not number.port) and CI is "boolean = false" so switching tabs is a git-diff of the same rules. Hero install and outro install: command pill and copy actions consume RELEASE_CONFIG.initCommand from apps/www/lib/config/release.ts (bare $ npx arkenv init while product latest points at RC; INSTALL_TAG is empty independently of the RC channel badge). A sub-row under it is “Copy prompt / View repo” (hero) or “Copy prompt / Read the docs” (outro). Channel badge uses RELEASE_TAG; install CTAs use INSTALL_TAG. Outro is a full-width bento span (“Start validating with ArkEnv” + the same command pill + “Copy prompt / Read the docs”), not a rounded inset card. Outro heading is heading-32 (--text-heading 32px / 40px / 450), not a display size. No outro subline. No Modular validator tabs — the hero example window is the only tab bar.
  • Homepage hero subhead: "Get a strictly typed env object using your existing TypeScript validator. No boilerplate. Zero runtime dependencies."
  • Site tagline (footer and similar surfaces): "Typesafe environment variables with ArkType, Zod, or Valibot."
  • Homepage <title> is punchy: "ArkEnv - Typesafe environment variables for TypeScript" (ASCII hyphen, not an en-dash). Docs pages use [Page] | ArkEnv (pipe, no "Docs"). Library names (ArkType, Zod, Valibot) go in <meta name="description">, not the title. Middle dots (·) are for on-page text only.
  • "Zero runtime dependencies" is true of @arkenv/core (peer arktype only) and @arkenv/standard (none). It is not true of the CLI or framework plugins (they depend on @arkenv/build, jiti, chokidar, etc.).
  • Docs use package-install tabs and stock Node defaults for user-facing runner / install copy (npx, node --env-file, framework loaders). Nub appears as an extra package-manager tab (nubx / nub add) generated from the npm fence; it is not the default selected tab. Dedicated Nub runner guidance lives in Using ArkEnv with Nub.
  • turborepo.dev is the visual and docs-voice reference; clone its docs into a gitignored folder when needed.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.