Penv Cloud
Start free
Docs
Guidesince 1.0.0-alpha.3

Upgrade from 0.16

Move from penv 0.16 to 1.0: export values, remove 0.16, install 1.0, push each environment, and the mapping from every 0.16 file, command and variable.

penv 1.0 is one static binary; 0.16 was a Node launcher with a downloaded engine, value files and plugins, and none of it carries over. You export one plain file per environment from 0.16 and push each to us.

Migrate

Export each environment with 0.16 still installed.

penv generate --env development --out .env.development --allow-decrypt
penv generate --env production --out .env.production --allow-decrypt

--allow-decrypt writes sealed values as plaintext; without it generate skips them and the file is incomplete.

Move the files outside your repository. They are plaintext, and a later step deletes the tree they came from.

mkdir -p ~/penv-move
mv .env.development .env.production ~/penv-move/

Remove 0.16: the global launcher and its engine store.

npm rm -g @penvhq/launcher
rm -rf ~/.penv/engines ~/.penv/extensions

Install 1.0. Windows and npm: install the CLI.

curl -fsSL https://penv.cloud/install | sh

Write the schema from the development values.

cp ~/penv-move/.env.development .env
penv init
penv check

penv init writes .env.schema, inferring a type and sensitivity per key. Review the guesses with penv check; inference rules: from a .env file.

Push the first environment.

penv login
penv push

penv login signs you in; penv push creates the project with development and the environment it pushes, writes the @penv= header into .env.schema, sends us the values and deletes the value files it read.

Create and push each remaining environment. push reads .env and .env.<env>, so copy the file back first.

penv env new production
cp ~/penv-move/.env.production .env
penv push --env production

penv env new creates the environment; penv refuses a push to one that does not exist as no_such_environment. Console alternative: projects and environments.

Confirm every environment lists its keys, with penv ls or in the console. Until then your plaintext copies are the only source.

penv ls --env production

Delete the 0.16 leftovers, then the holding directory. Keep .penv/config.toml, which 1.0 writes.

rm -f penv.config.ts penv.schema.ts .penv/env.ts
rm -rf .penv/state ~/penv-move

Also remove any @env or #env path mapping from tsconfig.json or package.json.

The files generate --allow-decrypt writes hold every value in the clear. Delete them once every environment lists its keys, and confirm none reached a commit. A value you sealed under a local key in 0.16 has no other way across: 1.0 cannot read the penv:1: envelope format.

Configuration mapping

Nothing in the 0.16 column exists in 1.0.

0.161.0
penv.config.ts and defineConfigOne committed .env.schema; no config file to import.
penv.schema.ts and .penv/env.tspenv gen ts writes the typed accessor from the schema.
The @env and #env aliasThe target decides the import line, stored under [targets.<name>] in .penv/config.toml.
.penv/state/records/Value files (.env, .env.local, .env.<env>, .env.<env>.local) in local mode; our store in cloud mode (local and cloud modes).
.penv/state/manifest.jsonNone; there is no engine to pin.
.penv/state/extensions/, local-extensions.jsonNone.
.penv/state/cutover.json, rollback/None; penv init leaves .env in place until push.
The four-scope cascadeOne environment per read: --env, then PENV_ENV, then the @currentEnv key, then development (precedence).
Providers and provider extensionsLocal and cloud modes, built in; @penv=<provider>:org/project names a provider, and 1.0.0-rc.1 has one, penv (schema format).
@penvhq/provider-penv-cloudNone; cloud mode is the binary. Never published, so nothing to remove.

Command mapping

0.161.0
penv initpenv init, which writes .env.schema from .env.
penv import <file>penv init.
penv generatepenv pull, which writes a plain .env from the cloud.
penv get <key>penv reveal; under a coding agent it needs a person's approval.
penv set <key> [value]penv set.
penv fillpenv set, one key at a time.
penv mv <from> <to>None.
penv pullpenv pull, reading from the cloud.
penv pushpenv push, sending to the cloud and deleting .env.
penv rotate <key>penv set writes a new version; @rotate in the schema sets a reminder interval.
penv runpenv run.
penv remove <key>penv unset.
penv listpenv ls.
penv cleanupNone; there is no rollback bundle.
penv migrateNone.
penv encrypt, penv decryptSame names since 1.0.0-beta.2 (penv encrypt, penv decrypt): they encrypt the sensitive values in the value files beside .env.schema as enc:v1:, under a keychain key or PENV_LOCAL_KEY. They do not read penv:1:.
penv key createNone in the binary. You set a customer-managed wrapping key in the console on Enterprise, or on Pro with the add-on (BYOK).
penv validatepenv check.
penv doctorpenv check, plus penv with no arguments, which prints the state and the next command.
penv watchNone.
penv artifact buildNone; penv pull writes a plain .env.
penv installNone; the installer places the binary.
penv add <package>None.
penv upgrade [version]penv upgrade replaces the binary with the latest release, or with next or a named version (upgrade penv).

New in 1.0:

CommandPurpose
penv login, penv logoutDevice-code sign-in.
penv machine enrollCredential for a host that can prove nothing.
penv project, penv envManage projects and environments from the terminal.
penv genTyped access per language.
penv guard, penv hookKeep a coding agent out of .env.

penv gen is not 0.16's penv generate. gen writes typed access for a language; the old generate wrote a value file, which penv pull does now.

Variable mapping

0.161.0
PENV_ENVPENV_ENV.
NODE_ENV as an environment fallback# @currentEnv=$NODE_ENV in the schema header, after --env and PENV_ENV.
PENV_HOMEPENV_INSTALL_DIR, read by the installers. There is no engine store.
PENV_KEY_*PENV_LOCAL_KEY, one 64-hex key for enc:v1: values; it cannot open penv:1:.
PENV_DELIVERY, PENV_SNAPSHOT, PENV_RUN, PENV_SCHEMA_HARVEST, PENV_DEBUGNone.
PENV_CLOUD_TOKENPENV_TOKEN, holding a pck_ machine credential.

Full 1.0 list: the variables penv reads.

Encryption

0.161.0
Where values are sealedOn diskBy us, under your workspace's key
Cipher and keyAES-256-GCM, 32-byte key from PENV_KEY_<ID> or the OS keychainServer side: encryption in the cloud
FormatOne-line penv:1: envelopeNo local envelope
Local copyNot applicableCache: ChaCha20-Poly1305, key in the OS keychain. Opt-in enc:v1: values in value files

No converter exists between the two; the generate --allow-decrypt export is the path across.

Random values

random(N) is a validation failure from 1.0.0. Write random(length=N); kind= is alnum, hex, base64url or uuid. Functions.

-SESSION_SECRET=random(32)
+SESSION_SECRET=random(length=32)

npm packages

npm view @penvhq/cli dist-tags shows:

TagVersion
latest1.0.0
nextPrereleases
CommandInstalls
npm i -g @penvhq/cli1.0.0, the release these pages describe
npm i -g @penvhq/cli@nextThe newest prerelease
curl -fsSL https://penv.cloud/install | shThe latest release, no tag needed

0.16.2 is deprecated; its only executable was penv-engine. In 0.16 the penv command came from @penvhq/launcher, which is no longer on the registry.

Next: changelog.