github.com-vercel-vercel
all · 44 devs · built 2026-06-13
Repository snapshot
Monthly reports
Highlights
- Introduced robust *Vercel CLI* authentication for `vc env pull` using step-up device-code flow, improving sensitive environment variable access [92988c2a · MelkeyDev].
- Streamlined *Vercel CLI* native binary installation by refactoring `@vercel/vc-native` to use a single `postinstall.mjs` script, removing the need for multiple package manager installs [446bc5ba · MelkeyDev].
- Added `vercel connect revoke-tokens` subcommand to the *Vercel CLI*, enhancing *security and administrative control* over Vercel Connect access tokens [0b4e1eff · Bhrigu Srivastava].
- Integrated `@vercel/connect` into the monorepo, bringing new capabilities and bug fixes for *Ash*, *Auth.js*, and *Better Auth* integrations [dddcc01d · Jathin Pranav Singaraju].
- Enabled *Python bytecode pre-compilation* in the build process, optimizing application startup times and deployment performance for *Python projects* [4f782b11 · Greg Schofield].
- Introduced the new `@vercel/aws` package with `createOpenSearch()` to simplify *AWS OpenSearch client* creation and integration for Vercel customers [11e2a419 · miketoth].
- Added `vercel domains check` command and bulk pricing support to the *Vercel CLI*, significantly improving *domain management features* [ff2a980b · Elliot Dauber].
- Implemented *project manifest generation* for *Go*, *Ruby*, and *Rust builders*, standardizing build output and providing richer metadata for dependency management and service introspection [73dbbe6b · dnwpark], [baac1493 · dnwpark], [6860c320 · dnwpark].
- Introduced *cold start improvements* for *Python functions* through enhanced dependency externalization and optimized Lambda environment configuration [13186826 · Greg Schofield].
- Added new filtering capabilities (`--type`, `--service`, `--search`) to `vercel connect list` in the *Vercel CLI*, improving discoverability and management of integrations [620bcfa9 · Bhrigu Srivastava].
- Streamlined developer workflow by adding `--open` and `--view` flags to `vc traces get` in the *Vercel CLI*, allowing direct access to *Vercel Dashboard* traces [2c17a12f · Andrew Gadzik].
Observations
- Overall development output decreased by 9% (40 current vs 44 2-month average), with a 27% reduction in grow score (16 current vs 22 2-month average) and a 21% decrease in total commits (182 current vs 230 2-month average) compared to the 2-month average.
- Waste score increased by 29% (5 current vs 4 2-month average) compared to the 2-month average, indicating a notable rise in rework or discarded efforts.
- A significant portion of waste commits (8 commits) were dedicated to *bug fixes* across various components, including *React Router* prerendering [2d918b8a · Jeff See], *CLI evaluation graders* [ba6e7c67 · Josh Souphanthong], *CLI HTTP client retries* [3986bb05 · Josh Souphanthong], *standalone prebuilt deployments* [b66bd3ed · Jeff See], *Python OTEL layer detection* [0e04bc51 · Greg Schofield], and *CLI release workflows* [2266b242 · MelkeyDev].
- The *Vercel CLI* was a major focus area, receiving numerous new features and enhancements, including improved authentication, token revocation, domain management tools, and trace viewing capabilities. This high activity also correlated with several CLI-related bug fixes.
- The *build system* and *language runtimes* (especially *Python*, *Go*, *Ruby*, *Rust*) saw substantial investment in new capabilities like project manifest generation and performance optimizations, indicating a push towards standardized metadata and improved build efficiency across different ecosystems.
- Several commits categorized as `maintenance` introduced significant new capabilities or refactorings, such as supporting `experimentalServices` in build output [14445024 · JJ Kasper], adding *Edge Runtime support* for OIDC token retrieval [5a700dc6 · Luis Meyer], and improving *CLI deployment scope lookup speed* through client-side caching [57ea4ba6 · MelkeyDev].
Performance over time
ETV stacked by Growth, Maintenance and Fixes — 90-day moving average, normalized to ETV / month.
Average performance per developer
ETV per active developer per month — 30-day moving average.
Active developers over time
Unique developers committing each day — 90-day moving average.
Knowledge concentration
How dependent is this repo on a small number of contributors? Higher top-1 share = higher key-person risk.
Jeff See owns 13.6 % of commits.
Top contributors
Most impactful commits
Top 20 by ETV in the all-time window.
- 2.3ETV[CLI] Updating the Vercel CLI Evals (#16136) This PR adds and tightens Vercel CLI agent eval coverage, including env, list, logs, inspect, project, pull, and curl scenarios. Also persists agent-eval model metadata during result upload so the dashboard can distinguish configured models from resolved runtime models. _deploy build curl/explicit curl/implicit env/add env/ls env/pull env/remove env/update init inspect link list login-whoami login-not-logged-in logs marketplace/find-postgres-integration marketplace/install-neon-postgres marketplace/metadata-discovery marketplace/multi-product-install non-interactive project/inspect project/list pull **New evals added in this PR:** inspect list logs project/inspect project/list pull **Also improved existing evals:** curl/explicit curl/implicit env/add env/ls env/update login-not-logged-in login-whoami non-interactiveMelkeyDev · a3a1a5a3 · 2026-05-16
- 1.8ETVauth: Make it possible to store CLI credentials in OS keychain, take 2 (#16264) Storing credentials in OS keychain is materially safer than plaintext files: - keychains are encrypted at rest by the OS, hence protect from cold-boot attacks; - access to the keychain can be mediated by OS security controls (login context, prompts etc); - credentials are less likely to be exposed by accident (e.g dotfile commits, agent reads etc). Specific changes: CLI credentials storage is made configurable via the new `"credStorage"` global config var or the `VERCEL_TOKEN_STORAGE` environment variable (env > config). Possible values are - `"keyring"` -- store credentials in the system keychain, via `@napi-rs/keyring` which is a Node binding for `keyring-rs`, both of which are widely used (the latter by Codex); - `"file"` -- store credentials in `<config-dir>/auth.json`, which is the current behavior and is still the default; - `"auto"` -- use keyring, if available, otherwise fall back to "file". When credentials are successfully written to a keychain, the previous copy in plaintext file is removed to avoid confusion. Additionally, credentials are auto-migrated on storage changes on read, which would allow us to change the default method in the future without breaking sessions. Unlike the previous take in 24686d0ea, which was reverted, this approach does not add an indirect native dependency to `@vercel/oidc` and uses the CLI as the authentication helper instead for cases when keyring reads are deemed necessary (via `cli-exec`). Note: `getVercelToken()` helper exported by `@vercel/oidc` will not work properly when credentials are not stored in plain text (i.e effective `file` mode).Elvis Pranskevichus · fddeb55f · 2026-06-02
- 1.7ETV[python-analysis] Add requirements.txt parsing via `uv-requirements-txt` (#15498) Add `parse-requirements-txt` WIT export for parsing requirements.txt files into structured data (PEP 508 specifiers, VCS URLs, extras, markers, index URLs, etc.). The upstream uv crate has several dependencies that are either too heavy for WASM or pull in async runtimes. These are satisfied by minimal stub crates (same interface, trivial internals): - `uv-client-stub`: offline-only connectivity (no HTTP client) - `uv-configuration-stub`: --no-binary/--only-binary option types - `uv-distribution-types-stub`: requirement wrapper types - `uv-fs-stub`: path utilities + file reading via host-bridge - `fs-err-stub`: absorbs tokio feature flag without pulling in tokio, (`fs-err` is only used in tests, but Cargo pulls it nonetheless). The host-bridge `read-file` function enables the upstream parser to resolve `-r`/`-c` includes through the WASM host. All async I/O resolves synchronously via the host-bridge, so a single-poll executor (`Waker::noop()`) drives the upstream async API. Also rename current `uv-fs-patch` to `uv-fs-stub` for naming consistency. Before: Binary Overview ─────────────── Total (code+data): 1,721,148 bytes (1.64 MB) Code: 499.5 KB ████████▉ 29.7% Data: 1.15 MB █████████████████████ 70.3% .rodata: 1.13 MB .data+.bss: 25.2 KB Top 10 Crates by Size ───────────────────── total code data % ───────────────────────────────────────────────────────────────────────────────────────────── 1. unicode_names2 823.9 KB 4.8 KB 819.1 KB ████████████████████ 49.0% 2. encoding_rs 169.4 KB 40.6 KB 128.8 KB ████ 10.1% 3. core 134.7 KB 88.9 KB 45.8 KB ███ 8.0% 4. unicode_normalization 111.0 KB 2.2 KB 108.8 KB ██ 6.6% 5. ruff_python_parser 106.7 KB 96.2 KB 10.5 KB ██ 6.3% 6. alloc 55.6 KB 55.3 KB 239 B █ 3.3% 7. data_encoding 43.6 KB 42.6 KB 971 B █ 2.6% 8. vercel_python_analysis 23.8 KB 21.9 KB 2.0 KB 1.4% 9. uv_pypi_types 22.1 KB 20.3 KB 1.8 KB 1.3% 10. std 17.1 KB 13.9 KB 3.1 KB 1.0% After: Binary Overview ─────────────── Total (code+data): 3,227,476 bytes (3.08 MB) Code: 1.43 MB █████████████▉ 46.4% Data: 1.65 MB ████████████████ 53.6% .rodata: 1.54 MB .data+.bss: 115.1 KB Top 10 Crates by Size ───────────────────── total code data % ───────────────────────────────────────────────────────────────────────────────────────────── 1. unicode_names2 823.9 KB 4.8 KB 819.1 KB ████████████████████ 26.1% 2. regex_syntax 420.5 KB 113.0 KB 307.5 KB ██████████ 13.3% 3. core 289.8 KB 240.9 KB 48.8 KB ███████ 9.2% 4. regex_automata 246.7 KB 228.8 KB 17.9 KB █████ 7.8% 5. encoding_rs 169.4 KB 40.6 KB 128.8 KB ████ 5.4% 6. alloc 116.5 KB 116.0 KB 502 B ██ 3.7% 7. unicode_normalization 111.0 KB 2.2 KB 108.8 KB ██ 3.5% 8. ruff_python_parser 106.7 KB 96.2 KB 10.5 KB ██ 3.4% 9. aho_corasick 92.1 KB 84.4 KB 7.7 KB ██ 2.9% 10. icu_normalizer 75.1 KB 6.4 KB 68.7 KB █ 2.4%Elvis Pranskevichus · 3c4355fa · 2026-03-13
- 1.5ETVAdd package manifest for Node deployments (#15991) Generate `PROJECTMANIFEST` to `@vercel/backends`, similar to `@vercel/python` but for node services. - `generateProjectManifest` reads `package.json` and the lock file to produce `package-manifest.json` - adds a `diagnostics` hook which is used to collect the manifest Supports: - `npm`: v1, v2, v3 - `pnpm`: v5-6, v9 - `yarn`: v1, berry - `bun`: text, (binary falls back to direct deps only) - `vlt`: falls back to direct deps onlydnwpark · 055f6239 · 2026-04-17
- 1.4ETVnon-interactive mode for env (#14912) Without flag ``` brookemosby@mac cli % pnpm vc env pull --cwd="../../../test-custom-deployment-id" ... Error: Your codebase isn’t linked to a project on Vercel. Run `vercel link` to begin. ELIFECYCLE Command failed with exit code 1. ELIFECYCLE Command failed with exit code 1. brookemosby@mac cli % ``` With flag ``` brookemosby@mac cli % pnpm vc env pull --non-interactive --cwd="../../../test-custom-deployment-id" ... { "status": "error", "reason": "not_linked", "message": "Your codebase isn't linked to a project on Vercel. Run vercel link to begin. Use --yes for non-interactive; use --project and --scope to specify project and team.", "next": [ { "command": "vercel link --non-interactive --cwd=../../../test-custom-deployment-id --yes" }, { "command": "vercel env pull --non-interactive --cwd=../../../test-custom-deployment-id --yes" } ] } ```Brooke · d269bdc1 · 2026-02-20
- 1.4ETV[python-runtime] Add tests (#15133) Configure the standard suite of linters, typecheckers and add tests to cover the existing implementation as much as possible. <!-- VADE_RISK_START --> > [!NOTE] > Low Risk Change > > This PR adds test infrastructure, linter/typechecker configuration, and test fixtures for the Python runtime with no changes to production code logic. > > - New GitHub Actions workflow for Python runtime tests > - Adds pytest, mypy, ruff, and basedpyright configuration in pyproject.toml > - Extensive test suite with fixtures for HTTP/WSGI/ASGI handlers > > <sup>Risk assessment for [commit b616f1b](https://github.com/vercel/vercel/commit/b616f1baf3cc5f19d97b58e7253f5d84c3412237).</sup> <!-- VADE_RISK_END -->Elvis Pranskevichus · cf1cc469 · 2026-02-19
- 1.3ETV[CLI] feat: Marketplace integration lifecycle parity scope (CLI-237) (#15849) ## Summary Scope note for [CLI-237](https://linear.app/vercel/issue/CLI-237/parity-vercel-marketplace-integration-install-configure-remove-cli): install/configure/remove vs `vercel integration` / `integration-resource`, dedup vs CLI-224/225. ## Path `packages/cli/docs/parity/cli-237-marketplace-integrations.md` Made with [Cursor](https://cursor.com) <!-- commands-to-test:start --> ### Supported API-backed Commands To Test - `vercel integration installations` - `vercel integration installations --integration <slug-or-id>` - `vercel integration installations --format json` <!-- commands-to-test:end -->Brooke · 48ea2ae0 · 2026-04-09
- 1.3ETVcli: Extract global config helpers to a new package, validate config (#16186) Current global configuration logic is firmly embedded in the main CLI package which makes it hard to reuse in library bits that might want to rely on configuration in library code. Remedy this by pulling the configuration lookup and I/O logic to the new `@vercel/cli-config` package. While here, add config validation via `@effect/schema`. This is a behavior change because the CLI will now fail loudly on invalid config data instead of continuing and possibly failing in worse ways somewhere deeper in the command implementation. Unknown config properties are ignored and passed through for 180-degree compat with versions of the CLI or other consumers. Additionally, while working on this I realized that a bunch of places were reading and writing global configuration directly and not via the `Client` interface, so I fixed some of those (notably `auto-install-agentic`).Elvis Pranskevichus · 34f595a2 · 2026-05-06
- 1.3ETV[CLI] feat: adding in non-interactive for routes command (#15502)Brooke · bf100177 · 2026-03-18
- 1.3ETV[CLI] non-interactive mode for teams (#15478)Brooke · f4c24437 · 2026-03-13
- 1.3ETVfeat(cli): add api command (#14715) Introduces a new vercel api command that allows making authenticated HTTP requests to the Vercel API. Similar in API to `gh api` Designed to improve discovery of our APIs for agents. ``` Vercel CLI 50.4.11 api (beta) — https://vercel.com/feedback ▲ vercel api [endpoint] [options] Make authenticated HTTP requests to the Vercel API Options: -F, --field <KEY=VALUE> Add a typed parameter (numbers, booleans parsed). Use @file for file contents --format <FORMAT> Output format for ls command (table, json). Defaults to table --generate <FORMAT> Generate output instead of executing (e.g., --generate=curl) -H, --header <KEY:VALUE> Add a custom HTTP header -i, --include Include response headers in output --input <FILE> Read request body from file (use - for stdin) -X, --method <METHOD> HTTP method (GET, POST, PUT, PATCH, DELETE). Defaults to GET, or POST if body is provided --paginate Fetch all pages of results --raw Output raw JSON without pretty-printing -f, --raw-field <KEY=VALUE> Add a string parameter (no type parsing) --refresh Force refresh the cached OpenAPI spec --silent Suppress response output --verbose Show debug information including full request/response Examples: - Get current user information $ vercel api /v2/user - List projects with team scope $ vercel api /v9/projects --scope my-team - Create a new project $ vercel api /v10/projects -X POST -F name=my-project - Delete a deployment $ vercel api /v13/deployments/dpl_abc123 -X DELETE - Paginate through all deployments $ vercel api /v6/deployments --paginate - Post JSON from file $ vercel api /v10/projects -X POST --input config.json - Add custom header $ vercel api /v2/user -H "X-Custom-Header: value" - List all available API endpoints $ vercel api --ls - Interactive mode (select endpoint) $ vercel api ``` --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>Thomas Knickman · de34a47a · 2026-01-23
- 1.2ETVUpgrade a few straddlers to TypeScript 5.9 (#16253) I missed a few spots in #16169. This finishes the job. Markdown doc changes are due to the necessary `typedoc` upgrade.Elvis Pranskevichus · ae202176 · 2026-05-08
- 1.2ETV[python/vercel-workers] refactor queue sdk logic into `_queue/` (#16171) Keeps behavior unchanged, refactors queue SDK logic into `_queue/` to start untangling the workers runtime from the queue sdk and make it easier to move this code into the `vercel/vercel-py` repoRicardo Gonzalez · 6935baa9 · 2026-05-01
- 1.1ETV[python] Add `diagnostics` callback to produce `project-manifest.json` (#15373) Introduce a `diagnostics` export to the Python builder that returns a `package-manifest.json` file containing structured project metadata: runtime, resolved Python version, and a full dependency inventory. `generateProjectManifest` collects dependencies from all `pyproject.toml` sources (`project.dependencies`, `optional-dependencies`, `dependency-groups`), classifies each as direct or transitive, and resolves versions and source info (registry, git, path, etc.) from the `uv.lock` file. Transitive dependencies inherit scopes from their direct dependents via BFS through the lock file's dependency graph. A dependency that appears in multiple groups (e.g. both `main` and `dev`) accumulates all scopes. The manifest is only generated when a `uv.lock` file is available; builds without one (e.g. custom install commands) skip manifest creation. The `diagnostics` callback is wired into the builder contract so the build system can collect the manifest after the build completes. Example `package-manifest.json`: ```json { "version": "20260304", "runtime": "python", "runtimeVersion": { "requested": ">=3.10", "requestedSource": "pyproject.toml", "resolved": "3.12" }, "dependencies": [ { "name": "flask", "type": "direct", "scopes": ["main"], "requested": "flask>=2.0", "resolved": "3.1.0", "source": "registry", "sourceUrl": "https://pypi.org" }, { "name": "werkzeug", "type": "transitive", "scopes": ["main"], "resolved": "3.0.0" } ] } ``` <!-- VADE_RISK_START --> > [!NOTE] > Low Risk Change > > This PR adds a new diagnostics feature to generate a project manifest JSON file containing dependency metadata; it only adds new code paths for metadata collection without modifying existing build logic, auth, or database schemas. > > - New `diagnostics.ts` file with `generateProjectManifest` function to produce metadata JSON > - Exports `parsePep508` and adds `specifier` field to existing types for version tracking > - Comprehensive test coverage added in `diagnostics.test.ts` > > <sup>Risk assessment for [commit 218f4e8](https://github.com/vercel/vercel/commit/218f4e8bd8252ea15d6d8592fc10a9250832b0f1).</sup> <!-- VADE_RISK_END -->Elvis Pranskevichus · 8e8110d2 · 2026-03-18
- 1.1ETV[python-analysis] Stub unicode/IDNA crates to reduce WASM size (#15499) Move IDNA and Unicode normalization operations out of the WASM binary and into the Node.js host via the new `host-utils` WIT interface. This eliminates ICU/Unicode lookup tables from the compiled component, using the host's native `URL` and `String.prototype.normalize` instead. Specifically: - `idna-stub`: delegates domain-to-ASCII/Unicode to host - `unicode-normalization-stub`: delegates NFC/NFD/NFKC/NFKD to host - `unicode-names2-stub`: returns Unicode replacement char (U+FFFD) as this is only used by the ruff parser to normalize Unicode name escapes in Python string literals (`\N{CAPITAL LETTER L}`) which is irrelevant to the analyses. - `host-bridge`: codegen crate for WASM host import bindings - `wasm-test-support`: test harness for running WASM tests with host fns Because the stub crates delegate to the JS host at runtime, their tests must run inside a WASM component with the real `host-utils` wired in. A custom `wasm-test-runner.mjs` is added and registered via `.cargo/config.toml` as the `cargo test --target wasm32-wasip2` runner. The runner transpiles each test binary with jco, instantiates it with the same `host-utils` implementation used in production, so `cargo test` works seamlessly for WASM targets. Before: Binary Overview ─────────────── Total (code+data): 2,865,491 bytes (2.73 MB) Code: 1.24 MB █████████████▌ 45.4% Data: 1.49 MB ████████████████▍ 54.6% .rodata: 1.39 MB .data+.bss: 106.5 KB Top 10 Crates by Size ───────────────────── total code data % ──────────────────────────────────────────────────────────────────────────────────────────── 1. unicode_names2 823.9 KB 4.8 KB 819.1 KB ████████████████████ 29.4% 2. regex_syntax 420.5 KB 113.0 KB 307.5 KB ██████████ 15.0% 3. core 255.8 KB 220.4 KB 35.5 KB ██████ 9.1% 4. regex_automata 246.7 KB 228.9 KB 17.9 KB █████ 8.8% 5. unicode_normalization 111.0 KB 2.2 KB 108.8 KB ██ 4.0% 6. ruff_python_parser 106.7 KB 96.2 KB 10.5 KB ██ 3.8% 7. alloc 96.3 KB 95.8 KB 502 B ██ 3.4% 8. aho_corasick 92.1 KB 84.4 KB 7.7 KB ██ 3.3% 9. icu_normalizer 75.1 KB 6.4 KB 68.7 KB █ 2.7% 10. uv_pep508 73.3 KB 66.4 KB 6.9 KB █ 2.6% After: Binary Overview ─────────────── Total (code+data): 1,716,626 bytes (1.64 MB) Code: 1.18 MB █████████████████████▋ 72.1% Data: 467.7 KB ████████▎ 27.9% .rodata: 369.0 KB .data+.bss: 98.7 KB Top 10 Crates by Size ───────────────────── total code data % ───────────────────────────────────────────────────────────────────────────────────────────── 1. regex_syntax 420.5 KB 113.0 KB 307.5 KB ████████████████████ 25.1% 2. regex_automata 246.7 KB 228.9 KB 17.9 KB ███████████ 14.7% 3. core 239.0 KB 203.6 KB 35.5 KB ███████████ 14.3% 4. ruff_python_parser 106.3 KB 95.9 KB 10.4 KB █████ 6.3% 5. alloc 94.3 KB 93.8 KB 502 B ████ 5.6% 6. aho_corasick 92.1 KB 84.4 KB 7.7 KB ████ 5.5% 7. uv_pep508 73.3 KB 66.4 KB 6.9 KB ███ 4.4% 8. uv_pep440 33.3 KB 28.6 KB 4.7 KB █ 2.0% 9. url 31.8 KB 29.6 KB 2.3 KB █ 1.9% 10. vercel_python_analysis 31.2 KB 28.7 KB 2.5 KB █ 1.9%Elvis Pranskevichus · 267223f8 · 2026-03-16
- 1.1ETV[cli] Add commands for bulk redirects feature (#14393) This PR adds new commands for `vercel redirects` to interact with the upcoming bulk redirects feature on Vercel. This feature allows users to manage redirects at the project level, without needing to change redirects from a deployment. https://github.com/user-attachments/assets/2a826f71-765c-400f-8f26-0d91c61b6ced The PR adds the following commands: - `list` - lists redirects with support for versions, searches, and pagination - `list-versions` - lists all redirects versions - `promote` and `restore` - for updating the live version - `add` and `remove` for adding and removing redirects The CLI commands will return `Error: Bulk redirects feature is not enabled for this team.` until this feature is enabled. --------- Co-authored-by: Austin Merrick <onsclom@onsclom.net>Mark Knichel · 5489c2d2 · 2025-12-04
- 1.1ETVAdd @vercel/backends package to consolidate backend framework builders (#14065) This introduces a new package (codename: `@vercel/cervel`) which can be used for generic node backends to both build and serve apps. It's in this monorepo, but isn't specific to any Vercel tooling, and it might make sense to move to it's own repo. - Wraps `srvx` with the `tsx` loader - Builds with `rolldown` - Shares the same entrypoint detection logic that we're using for the backend presets. The idea here would be that we'd update express/hono/etc framework presets with `build` and `dev` commands: ``` "dev": "cervel", "build": "cervel build index.ts" ``` While internally, if there's no build script we supply `cervel build` under the hood (which will autodetect an entrypoint if not supplied). --- This work is coming up during the o11y POC because we have exhausted how far we can get with using the `@vercel/node` builder. Essentially, the node builder is using version 3 of the build output API, and we need to use version 2. All of this is behind the `VERCEL_EXPERIMENTAL_BACKENDS=1` env var so should be safe to move forward with. --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>Jeff See · c6cf33d7 · 2025-10-28
- 1.1ETV[CLI] feat: non-interactive mode for link (#14884) If an agent is using, or a user passes in non-interactive flag, don't respond with interactive prompts. Instead output a response that the agent can easily parse, with next steps and kill process. I have been validating on my own project (and with cursor agent). Cursor agent defaults to non-interactive mode, meaning non-linked projects will exit CLI command with an error and output a json response. Example for vc open **Non-interactice Flow:** ``` brookemosby@mac cli % pnpm vc open --cwd=../../../test-custom-deployment-id --non-interactive ... { "status": "action_required", "reason": "confirmation_required", "message": "Command vercel open requires confirmation. Use option --yes to confirm.", "next": [ { "command": "vercel open --cwd=../../../test-custom-deployment-id --non-interactive --yes", "when": "Confirm and run" } ] } ELIFECYCLE Command failed with exit code 1. ``` **Regular Flow:** ``` brookemosby@mac cli % pnpm vc open --cwd=../../../test-custom-deployment-id ... Vercel CLI 50.15.1 ? Set up "~/Vercel/test-custom-deployment-id"? (Y/n) ... ``` --------- Co-authored-by: Cursor <cursoragent@cursor.com>Brooke · fb8a8c85 · 2026-02-13
- 1.0ETV[CLI] feat: non-interactive mode for redirects (#15450)Brooke · d8c186e7 · 2026-03-13
- 1.0ETVauth: Make it possible to store CLI credentials in OS keychain (#16083) Storing credentials in OS keychain is materially safer than plaintext files: - keychains are encrypted at rest by the OS, hence protect from cold-boot attacks; - access to the keychain can be mediated by OS security controls (login context, prompts etc); - credentials are less likely to be exposed by accident (e.g dotfile commits, agent reads etc). Specific changes: CLI credentials storage is made configurable via the new `"authTokenStorage"` global config var. Possible values are - `"keyring"` -- store credentials in the system keychain, via `@napi-rs/keyring` which is a Node binding for `keyring-rs`, both of which are widely used (the latter by Codex); - `"file"` -- store credentials in `<config-dir>/auth.json`, which is the current behavior and is still the default; - `"auto"` -- use keyring, if available, otherwise fall back to "file". When credentials are successfully written to a keychain, the previous copy in plaintext file is removed to avoid confusion. Additionally, credentials are auto-migrated on storage changes on read, which would allow us to change the default method in the future without breaking sessions.Elvis Pranskevichus · 24686d0e · 2026-04-28