4.3 KiB
4.3 KiB
AGENTS.md (envsitter)
This repo contains envsitter: a TypeScript (ESM) library + CLI for safely inspecting and matching .env secrets without exposing values.
Ground rules (security)
- Never print or log raw secret values from
.envfiles or external providers. - Do not add any API that returns a plaintext value (no
getValue()style APIs). - Prefer comparisons via deterministic fingerprints (HMAC) and boolean match results.
- Prefer passing candidate secrets via stdin (to avoid shell history):
--candidate-stdin. - Keep all generated peppers/secrets out of git (see
.gitignore).
Project layout
src/envsitter.ts: main library surface (EnvSitter)src/cli.ts: CLI entrypointsrc/dotenv/parse.ts: minimal dotenv parsersrc/pepper.ts: pepper resolution + auto-createsrc/test/*.test.ts: Node test suite (compiled todist/test/*.test.js)
Build / typecheck / test
There is no linter configured (no ESLint/Prettier). Use tsc + tests as quality gates.
Install
npm install
Build
npm run build- Runs
tsc -p tsconfig.jsonand outputs todist/
- Runs
Typecheck only
npm run typecheck
Run all tests
npm test- Runs
npm run buildthennode scripts/run-tests.mjs
- Runs
Run a single test file
Tests are written in TS but executed from compiled JS.
npm run buildnode --test dist/test/envsitter.test.js
Run a single test by name/pattern
npm run buildnode --test --test-name-pattern "outside-in" dist/test/envsitter.test.js
(Use a substring/regex that matches the test('name', ...) title.)
Bun
The CLI is runnable under Bun:
bun src/cli.ts keys --file .env
Tests currently run under Node’s built-in test runner. If you add Bun tests, keep Node tests working.
Code style and conventions
TypeScript / module system
- This repo is ESM:
"type": "module"inpackage.json. - TS config is strict and includes:
strict: truenoUncheckedIndexedAccess: trueexactOptionalPropertyTypes: true
- Use ESM import specifiers with
.jsextensions when importing local TS modules.- Example:
import { parseDotenv } from '../dotenv/parse.js'
- Example:
- Prefer
node:specifiers for built-ins:import { readFile } from 'node:fs/promises'
Formatting
- No formatter is enforced.
- Keep diffs small and consistent with existing file style.
- Prefer 2-space indentation and trailing commas where already used.
Imports
- Group imports by origin:
node:built-ins- third-party (if any)
- local
./and../
- Avoid unused imports; keep import lists minimal.
Naming
- Types:
PascalCase(EnvSitterFingerprint) - Functions/vars:
camelCase(resolvePepper,candidateValue) - Constants:
camelCaseunless truly global constant. - File names:
kebab-case.tsfor tests; otherwise match existing structure.
Types and optional properties (important)
exactOptionalPropertyTypes is enabled.
- Do not pass
undefinedas a value for an optional property.- Prefer conditional spreads:
...(maybe ? { prop: maybe } : {})
- Prefer conditional spreads:
- Prefer returning
undefinedby omitting optional properties rather than setting them.
Error handling
- Prefer throwing
Errorwith actionable messages. - Avoid empty
catchblocks. - Avoid logging by default. If debugging output is needed:
- Gate it behind
process.env.ENVSITTER_DEBUG === '1'.
- Gate it behind
Security-sensitive comparisons
- Use constant-time comparison for digests:
timingSafeEqualfor fingerprint digest bytes.
IO and side effects
.envvalues should only exist in memory.- Pepper auto-creation is allowed, but must write only to the gitignored location:
- default:
.envsitter/pepper
- default:
- Never write
.envvalues elsewhere (no caches, no exports to new files).
CLI behavior
- CLI should return useful exit codes:
0success / match found1mismatch / no match found2usage or runtime error
- Prefer JSON output for machine consumption when
--jsonis provided. - Never print secret values; only keys, booleans, metadata (length), and fingerprints.
Editor/assistant rules
- No Cursor rules found in
.cursor/rules/or.cursorrules. - No Copilot instructions found in
.github/copilot-instructions.md.
If you add any of the above rule files later, update this document to summarize the relevant constraints.