Skip to main content

gestate

Set a minimum release age on local package managers so installs ignore versions younger than N days. Most malicious packages are caught and yanked within days of publishing; refusing fresh versions blocks the bulk of supply-chain attacks.

Run

uvx gestate                  # interactive
uvx gestate set 3            # 3-day minimum, installed tools only
uvx gestate set 3 --all      # also pre-configure file-based tools (bun, deno, uv)
uvx gestate set 3 --local    # write per-project config files in the current repo
uvx gestate revert           # remove gestate's settings
uvx gestate revert --local   # remove the per-project gate from this repo
uvx gestate explain bun      # show how one tool's setting is stored
uvx gestate trust my-pkg --python  # exempt a package from the age delay
uvx gestate trust --rm my-pkg      # remove an exemption
uvx gestate trust                  # list trusted packages

Interactive mode always shows a plan and asks for explicit confirmation before touching anything. The subcommands skip the confirm — meant for scripts, not your daily shell. Running with no subcommand outside a TTY exits with an error.

Plain text output is used when stdout isn't a terminal (no Rich tables/colors).

What it sets

Tool Where Key (unit)
npm ~/.npmrc min-release-age (days)
pnpm global pnpm config minimumReleaseAge (minutes)
yarn ~/.yarnrc.yml (4.10+) npmMinimalAgeGate (minutes)
bun ~/.bunfig.toml [install] minimumReleaseAge (seconds)
deno shell profile alias deno='command deno --minimum-dependency-age=P<N>D'
pip user pip config global.uploaded-prior-to (P<N>D)
uv ~/.config/uv/uv.toml exclude-newer ("N days")

gestate explain <tool> prints that tool's current value and the exact mechanism set / revert use.

Scope:

  • default — only configure installed tools
  • --all — also pre-write config files for bun, deno, uv even if they aren't installed yet

Project-local policy (--local)

gestate set <days> --local writes each tool's native, committed-to-the-repo config so the gate travels with the project and applies to anyone who clones it — even collaborators who never ran gestate. It only configures tools the repo gives evidence of (a lockfile, manifest, or existing tool config in the current directory), so it won't litter a JS repo with uv.toml or vice versa.

Tool Project file (cwd) Key (unit)
npm .npmrc min-release-age (days)
pnpm pnpm-workspace.yaml minimumReleaseAge (minutes)
yarn .yarnrc.yml npmMinimalAgeGate (minutes)
bun bunfig.toml [install] minimumReleaseAge (seconds)
deno deno.json minimumDependencyAge (P<N>D)
uv uv.toml exclude-newer ("N days")

pip has no per-project config (and no dependency-age gate), so it's skipped. If a deno.json has comments (JSONC), gestate won't rewrite it — it prints the line to add yourself. revert --local removes the key and deletes any file it leaves empty.

Revert

uvx gestate revert removes everything gestate set:

  • CLI tools — config delete / config unset
  • bun / uv — remove the key; delete the file if it was the only key
  • deno — remove our alias line; leave foreign alias deno= lines alone

Backups (.bak) are written next to any edited shell-profile or TOML file.

Per-package exemptions (trust)

gestate trust lets you exempt specific packages from the age delay so they always get the latest version:

gestate trust @myorg/*              # auto-detects Node (scoped package)
gestate trust my-lib --python       # exempt in uv
 
gestate trust --rm my-lib --python  # remove exemption
gestate trust                       # list all trusted packages
gestate trust --python              # list Python ecosystem only

The --python / --node flags are optional — gestate auto-detects the ecosystem from scoped packages (@scope/name → Node) or the current directory (pyproject.toml → Python, package.json → Node). When it can't tell, it asks you to specify.

Supported tools: bun, uv, yarn, pnpm, npm (requires npm ≥ 11.17.0). deno and pip don't support per-package allowlists and print a warning. For manual config details, see docs/allowlists.md.

Caveats

  • yarn: 4.10+ only. Older yarn is detected and skipped.
  • deno: no global config exists; the shell alias only covers interactive shells. For CI, pass --minimum-dependency-age=P<N>D to deno install/deno update, or commit a project deno.json with "minimumDependencyAge": "P<N>D".
  • npm trust: requires npm ≥ 11.17.0. gestate skips npm with a note when the installed npm is older (global scope only — a project .npmrc is still written, since it's enforced by whoever installs). Early npm releases didn't honor min-release-age-exclude in npx or every reify path.
  • pip exclude: none — global.uploaded-prior-to is global only.

For PR-creation guards (Dependabot, Renovate) and adjacent layers, see docs/complementary.md.

Development

uv sync
uv run pytest

Requires Python 3.11+, macOS or Linux.

Metadata

Release files for gestate 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gestate 1.2.0
File Size Uploaded
gestate-1.2.0.tar.gz 49.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gestate 1.2.0
File Interpreter ABI Platform
gestate-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 71.7 kB

Release files / gestate-1.2.0.tar.gz

Download URL gestate-1.2.0.tar.gz
Size 49.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e91f703fd35b042136f62096f981e826603ad8ab7edc790b0204d71a77b70e21
BLAKE2b-256 checksum
How to use checksums
aa8f16ddd2bfa9913de0af942ea4d8d6acf04eb8b0364aa299339a60385c4466
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / gestate-1.2.0-py3-none-any.whl

Download URL gestate-1.2.0-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
226b41906f46feb04d099d1fdf2d170989af830e29cc6aa33bcfec9e3b219adb
BLAKE2b-256 checksum
How to use checksums
832d2bdb2845a53ed01c89517dd00243053d5bb1b623c3f17ef6b8673c108563
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page