DEV Community

Oluwafemi
Oluwafemi

Posted on

penv 1.0.0-beta.1: project and env commands, a terminal UI, and what "beta" means here

Your coding agent can read .env. It also reads what it prints.

penv is a single Rust binary that validates a schema before your process starts, and keeps secret values out of files, the repo, shell history and agent output. 1.0.0-beta.1 shipped today.

npm i -g @penvhq/cli@next
# or
curl penv.cloud/install | sh
Enter fullscreen mode Exit fullscreen mode

Repo: github.com/penvhq/penvhq · Release: v1.0.0-beta.1

Start without an account

penv init
penv run -- npm run dev
Enter fullscreen mode Exit fullscreen mode

penv init writes one committed file, .env.schema. It is a varlock @env-spec file; the decorators (@type, @required, @sensitive, …) are documented at varlock.dev/env-spec/reference. Migrating an existing .env into one: this guide.

A value that fails the schema exits 3 before npm run dev starts.

Under an agent

penv guard
Enter fullscreen mode Exit fullscreen mode

Detects the running harness and writes its deny rules for .env and .env.*. Claude Code, Codex, Cursor, Copilot CLI, Gemini, Amp, Cline, Windsurf. --all writes every one. What each harness actually reads: Eight coding agents, eight deny-list formats.

Inside an agent session, penv run masks secret values in the child's stdout and stderr: raw, hex, base64 and URL-encoded forms. penv reveal is refused. Output is JSON.

New in beta.1

penv project and penv env

penv project ls | new | rename | rm
penv env     ls | new | rename | copy | rm
penv ls --env staging
Enter fullscreen mode Exit fullscreen mode

-p <project> is optional inside a linked folder. rm asks a person to type the name. From an agent or a pipe it exits 4 and prints the command to run.

Terminal UI

Pickers, spinners on network calls, tables, and refusals written as sentences. Drawn on stderr, only when a person is at a TTY. Piped, JSON and agent sessions get the same plain lines as before.

penv push refuses before the server is contacted

refusal when
nothing_to_push .env is missing or has no values. An empty first push no longer creates a project.
no_such_environment --env names an environment the project does not have. Lists the ones that exist.
org_mismatch --org contradicts the schema's @penv= header. Previously ignored.

A new project is created with the environment being pushed, not only development.

penv pull

  • Values containing quotes and line breaks round-trip, written in whichever literal quote the value lacks.
  • A \r in the file no longer blocks the pull.
  • A partial write reports the keys it skipped instead of failing the whole pull.
  • A folder with no @penv= header can be linked to a project the account already has.

Also

  • Dynamic value injection fixed for Next.js.
  • Release notes are generated from merged PRs; npm provenance verifies against penvhq/penvhq.

What beta means here

  • No more breaking changes planned before 1.0.
  • Bugs expected. Issues are open.
  • @since, @rotate and @dynamicFrom semantics get documented at RC.

MIT. One static binary. No runtime.


Disclosure: this post was generated by an AI from the release changelog on GitHub and reviewed before publishing. If anything here disagrees with the code, the changelog is right and I'd appreciate a comment pointing it out.

Top comments (0)