v0.13.0
Bundles the file-scoped export, shell-hook injection, and fail-fast key-handling work.
Added
envpkt shell-hooknow loads and unloads project credentials oncd(previously
audit-only). The emitted zsh/bash hook resolves the directory's package, injects it via
env export --track, restores the previously-injected package on leave (prior values, not a
blind unset — no cross-project bleed), and prints a health warning. Secret values load only
forscope = "shell"packages; env defaults always load. Decryption happens only when the
resolved package changes.envpkt config-path— resolve-only command that prints theenvpkt.tomlpath for the
current directory (empty if none), with no config load or decryption. Powers the shell hook's
per-cdgate and is useful in scripts.- Upward-walk config discovery —
discoverConfignow walks up from the current directory to
the nearestenvpkt.toml(likegit/direnv) before the global/search fallback, so a
project's config applies throughout its subtree. Affectsexec,env export,audit, and the
shell hook — running any of them from a subdirectory now finds the enclosing project. - Top-level
scopefield ("shell"|"exec", default"exec") gates whether
envpkt env exportemits a package's secret values for ambient shell loading.shell
exports them (foreval/the shell hook);exec(default) withholds them so they're only
available viaenvpkt exec. Env defaults (non-secret) are always exported.scopenever
affectsenvpkt exec,env github, orenv dotenv— those are deliberate, not ambient. envpkt env export --trackwraps each assignment with an in-shell prior-value snapshot
(_ENVPKT_HAD_*/_ENVPKT_PREV_*) and emits an_ENVPKT_INJECTEDname list, so a shell
hook can restore — not just unset — variables when leaving a directory. Plainenv export
output is unchanged.envpkt env dotenvemits resolved credentials in.envformat (KEY=value), for the
tools that auto-discover.envfiles — Wrangler, Docker--env-file, Vite/Next/Astro,
GitHub Actions, direnv. A sibling ofenv export(shell) andenv github($GITHUB_ENV).
Secret values are included by default (consistent with those commands);--no-secrets
emits value-less placeholders.-o <file>writes to a file (with a.gitignorereminder
when secrets are present). Values are quoted only when needed and output is deterministic.
New library API:formatDotenv/quoteDotenvValue.
(#23)secret edit --unset <field>removes an optional metadata field (repeatable). Field
names are the canonical TOML keys (e.g.rate_limit). You can unset any field you can set
with a flag; unknown field names are rejected rather than silently ignored. Previously the
only way to drop a field was hand-editing the TOML, since--field ""failed schema
validation. (#31)
Changed
envpkt seal --editnow confirms before overwriting an already-sealed value. Replacing a
sealedencrypted_valuediscards the only ciphertext, so--editasksReplace the sealed value for <KEY>? [y/N]first (declining keeps the existing value). Editing an unsealed entry is
unaffected. Makes the "lost the key, re-provision from source" path a deliberate act.envpkt env exportno longer emits secret values by default. With the newscopefield
defaulting to"exec", ambienteval "$(envpkt env export)"now exports only env defaults; add
top-levelscope = "shell"to a package to restore secret export (e.g. for a global package
loaded at shell start). Withheld secrets print a one-line note to stderr.envpkt exec,
env github, andenv dotenvare unaffected — they still resolve everything.
Fixed
boot()/bootSafe()now fail fast when a sealed packet's decryption key is absent, instead
of warning and injecting empty values. A package withencrypted_valueentries and no resolvable
key (identity.key_file→ENVPKT_AGE_KEY_FILE→ENVPKT_AGE_KEY→~/.envpkt/age-key.txt)
returns aSealKeyUnavailableerror listing the searched paths and how to fix it — so a missing
key surfaces immediately (inexec/env export·github·dotenv) rather than as a confusing
empty-credential failure downstream. A configured-but-missingkey_filenow also falls through
the rest of the precedence chain (so a localkey_fileno longer blocks an inline CI key).
auditis unaffected — it reads metadata only and still reports health without the key.--dry-runnow runs the same schema validation as the real write acrosssecret
subcommands. Previously a dry-run could preview a change (e.g.expires = "") that the
actual write would then reject, so the preview no longer misrepresents what will be
accepted. (#31)
Full Changelog: v0.12.0...v0.13.0