Skip to content

Latest commit

 

History

History
89 lines (65 loc) · 7.31 KB

File metadata and controls

89 lines (65 loc) · 7.31 KB

Project conventions

Repo structure

This is a monorepo managed with bun workspaces and Turborepo:

  • packages/env-spec-parser — parser for the @env-spec language (PEG.js grammar in grammar.peggy)
  • packages/varlock — the main package: CLI + library for loading/validating .env files
  • packages/varlock-website — docs site (Astro); docs content lives in src/content/docs/
  • packages/vscode-plugin — VSCode extension for @env-spec language support
  • packages/integrations/* — framework integrations (nextjs, vite, astro, ...)
  • packages/native-helpers/* — per-platform npm publishing shells for the native helper binaries (published as @varlock/native-helper-*, versioned in lockstep with varlock); the binaries themselves are built from packages/encryption-binary-swift (darwin) and packages/encryption-binary-rust (linux/win32)
  • packages/utils, packages/plugins — shared internals
  • packages/varlock-docs-mcp — docs MCP server for external varlock users; do not use it to look things up while working on this repo — read the docs source directly

Package manager

  • This repo uses Bun as the package manager (bun install, bun run, etc.)
  • Workspace deps use workspace:* protocol
  • Use catalog for any potentially common dependencies
  • CI workflows use bun run to execute scripts and bunx for one-off commands

Building

  • bun run build at the repo root builds all packages via Turborepo, in dependency order
  • To build a single package, go through turbo so its workspace deps build first: bunx turbo run build from the package directory, or bunx turbo run build --filter=<pkg> from the root
  • Do not build a package with bun run --filter <pkg> build: bun's filter does not build the package's workspace dependencies, and some builds require their dist output to exist (e.g. varlock's d.ts bundling inlines the emitted declarations from packages/utils, so it fails if that package was never built)

Scripts

  • Write any scripts which may end up being saved in TypeScript (.ts), not JavaScript
    • throwaway/one-off code is fine in JS
  • Execute scripts using bun run, not node
    • e.g. bun run scripts/release-preview.ts
    • Bun runs .ts files natively — no compile step needed
  • Scripts in scripts/ at the repo root are monorepo-level utilities, while specific packages may have their own scripts folder

Binary builds

  • The varlock CLI binary is built using bun build --compile (not Node SEA or pkg)
  • bun run --filter varlock build:binary builds a local dev binary for the current platform at packages/varlock/dist-sea/varlock
  • packages/varlock/scripts/build-binaries.ts builds cross-platform release binaries (or use --current-platform for a single local binary)
  • bun run --filter varlock test:binary:local builds the local binary and runs a smoke load check (WSL-aware helper copy)
  • bun run --filter varlock pack:local builds + packs a local tarball and prints a ready-to-paste file: dependency

Testing

  • Unit/integration tests use Vitest
  • Smoke tests live in smoke-tests/ and test the CLI end-to-end
  • Binary-specific tests in smoke-tests/tests/binary.test.ts require the SEA binary to be built first

Versioning & releases

  • This monorepo uses bumpy (@varlock/bumpy) for version management
  • Changeset files live in .bumpy/ and are created with bunx @varlock/bumpy add (or bun run bumpy:add)
  • Standard bump types: major, minor, patch
  • Non-interactive changeset creation (for CI/AI): bumpy add --packages "pkg:minor" --message "description" --name "changeset-name"
  • Bump files are only required when publishable packages have changed (based on changedFilePatterns in .bumpy/_config.json). Changes to CI workflows, root config files, scripts, docs, etc. do not require a bump file — bumpy's pre-push hook will not block in that case.
  • Write changeset descriptions for end users, and keep them short
  • One bump file per package per PR is usually enough. Before adding a new one, check whether the branch already has a bump file for that package and extend its description instead. In particular, when the PR introduces a brand-new (never-published) package, keep a single entry describing the whole feature: its first changelog entry should read as one coherent release, not a series of additions and fixes to something that never shipped

Branches & pull requests

  • Branch names must be meaningful — a short kebab-case description of the change (e.g. fix-cf-fifo-secret-concat, vite-plugin-hmr). Never push an auto-generated session/worktree branch name (e.g. claude/dreamy-jones-a79c22); rename it first with git branch -m <meaningful-name>
  • Do not push after every commit. Pushes to open PRs trigger automated reviews that cost money. Commit locally as you go, and only push when the work is complete (or the user asks for feedback on work in progress). When in doubt, ask before pushing
  • Do not add AI attribution to PRs or commits — no "Authored by Claude" / "Generated with Claude Code" lines in PR descriptions, and no Co-Authored-By: Claude commit trailers
  • Keep PR descriptions concise: what changed and why. Don't mention linting passing or bump files being added — those are enforced by hooks and expected, not news
  • When pushing new commits to an open PR, update the PR description if the changes alter what it says
  • If a change affects user-facing behavior, update the docs in packages/varlock-website/src/content/docs/ (guides and/or reference) in the same PR

Documentation

Docs content lives in packages/varlock-website/src/content/docs/ (.mdx). When writing or editing docs prose, keep the tone plain and direct, like an engineer wrote it:

  • No em dashes (). Rewrite into separate sentences, commas, colons, or parentheses instead. Do not swap in a spaced hyphen (-). (En dashes for genuine numeric ranges like 15.0–15.4 are fine.)
  • Avoid marketing and AI-flavored filler: seamless, comprehensive, powerful, robust, leverage, out of the box, by design, effortless, unlock (metaphorical), "whether you need X, Y, or Z", "instead of wrestling with", and similar. Say what the thing does plainly.
  • Be concise, but never at the cost of completeness. Keep every flag, command, caveat, and link a user or their agent needs to stay unblocked.
  • Never edit code fences, ansi/diff blocks, generated fixtures, frontmatter structure, or MDX component markup for tone. Prose only.
  • Run bun run --filter @varlock/website build to confirm the docs still build after non-trivial edits (the package is named @varlock/website, not varlock-website).

Linting

  • Run bun run lint:fix from the repo root after completing a significant chunk of work (new feature, refactor, bug fix, etc.)
  • The linter uses ESLint with @stylistic and other plugins; auto-fix handles most formatting issues
  • Do not leave lint errors unresolved; fix any that --fix cannot handle automatically

Writing style

  • Do not use em dashes () or en dashes () in any prose you write: docs, code comments, commit messages, PR descriptions, changeset entries, or design notes. They read as an AI-writing tell. Rewrite with a colon, comma, semicolon, parentheses, two sentences, or a plain hyphen (-) where that reads naturally. Only the em/en dash characters are banned; a regular hyphen is fine.