feat(cli): add --format=json to integration add (auto-provision)#15250
feat(cli): add --format=json to integration add (auto-provision)#15250
Conversation
…sion) Enable coding agents and CI scripts to parse structured output from `vercel integration add` when using the auto-provision flow. JSON is written to stdout via client.stdout.write(), while all intermediate messages (spinners, status, prompts) go to stderr via output.log/error/spinner. This follows Unix stream separation convention — agents read stdout for data and stderr for diagnostics. Refactors postProvisionSetup to return a structured result object (PostProvisionSetupResult) instead of just an exit code, so the JSON output path has access to project, environments, and env-pull status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: f2a4848 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📦 CLI Tarball ReadyThe Vercel CLI tarball for this PR is now available! Quick TestYou can test this PR's CLI directly by running: npx https://vercel-frc1gkigf.vercel.sh/tarballs/vercel.tgz --helpUse in vercel.jsonTo use this CLI version in your project builds, add to your {
"build": {
"env": {
"VERCEL_CLI_VERSION": "vercel@https://vercel-frc1gkigf.vercel.sh/tarballs/vercel.tgz"
}
}
}Python Runtime WheelA |
🧪 Unit Test StrategyComparing: Strategy: Affected packages only ✅ Only testing packages that have been modified or depend on modified packages. Affected packages - 3 (8%)
Unaffected packages - 37 (93%)
Results
This comment is automatically generated based on the affected testing strategy |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CI test ensures every addSubcommand option has a corresponding dynamic example. Adding formatOption to command options requires a matching entry in formatDynamicExamples(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Always include `project` field (null when absent) for stable contract - Move formatOption to end of options array (consistent with other cmds) - Extract env pull warning to shared ENV_PULL_FAILED_MESSAGE constant - Filter --format from help when auto-provision FF is off - Add ssoUrl.integration and ssoUrl.resource to JSON output via buildSSOLink() (no API calls, constructed from existing IDs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## vercel@50.24.0 ### Minor Changes - [dev] skip project setup for `vc dev` if `--local` or `-L` flag is passed. ([#15239](#15239)) ### Patch Changes - feat(cli): add --format=json support to `integration add` (auto-provision) ([#15250](#15250)) - Updated dependencies \[]: - @vercel/build-utils@13.5.0 - @vercel/next@4.15.34 - @vercel/redwood@2.4.9 - @vercel/rust@1.0.5 - @vercel/static-build@2.8.41 ## @vercel/routing-utils@5.4.0 ### Minor Changes - Undeprecate `routes` schema and add aliases for `src`, `dest`, and `status` ([#15010](#15010)) ## @vercel/client@17.2.47 ### Patch Changes - Updated dependencies \[[`0c961fce30d495620542066249dae447764d2eba`](0c961fc)]: - @vercel/routing-utils@5.4.0 - @vercel/build-utils@13.5.0 ## @vercel/config@0.0.34 ### Patch Changes - Undeprecate `routes` to match new routing-utils ([#15016](#15016)) - Updated dependencies \[[`0c961fce30d495620542066249dae447764d2eba`](0c961fc)]: - @vercel/routing-utils@5.4.0 ## @vercel/fs-detectors@5.8.11 ### Patch Changes - [services] adds source information to detected services ([#15245](#15245)) - Updated dependencies \[[`0c961fce30d495620542066249dae447764d2eba`](0c961fc)]: - @vercel/routing-utils@5.4.0 - @vercel/frameworks@3.19.0 <!-- VADE_RISK_START --> > [!NOTE] > Low Risk Change > > This PR is an automated Changesets release that only updates version numbers in package.json files and CHANGELOG.md files, with no code logic changes. > > - Version bumps across 5 packages (vercel, client, config, fs-detectors, routing-utils) > - Deletes consumed changeset markdown files > - Updates CHANGELOG.md files with release notes > > <sup>Risk assessment for [commit 987df11](https://github.com/vercel/vercel/commit/987df111fedc0eb57c982038befca199bbf7e6fe).</sup> <!-- VADE_RISK_END --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
--format=jsonsupport tovercel integration addfor the auto-provision path (FF_AUTO_PROVISION_INSTALL=1)postProvisionSetupto return aPostProvisionSetupResultobject instead of just an exit codeHow agents use this (stream separation)
The Vercel CLI already separates streams per Unix convention:
When a human runs the command, they see both streams interleaved on the terminal. When an agent runs it, it captures them separately:
The agent determines success/failure from the exit code (0 = success, 1 = error), not by parsing output. Intermediate messages (spinners, "Installing...", "Provisioning...") go to stderr and don't interfere with the JSON on stdout.
Output contract
00warningsarray1Example JSON output
{ "resource": { "id": "res_xxx", "name": "neon-blue-river", "status": "available", "externalResourceId": "ext_xxx" }, "integration": { "id": "int_xxx", "slug": "neon", "name": "Neon" }, "product": { "id": "prod_xxx", "slug": "neon-postgres", "name": "Neon Postgres" }, "installation": { "id": "inst_xxx" }, "billingPlan": { "id": "plan_xxx", "name": "Free", "type": "subscription" }, "dashboardUrl": "https://vercel.com/team/~/stores/integration/res_xxx", "ssoUrl": { "integration": "https://vercel.com/api/marketplace/sso?teamId=...&integrationConfigurationId=inst_xxx", "resource": "https://vercel.com/api/marketplace/sso?teamId=...&integrationConfigurationId=inst_xxx&resource_id=ext_xxx" }, "project": { "id": "prj_xxx", "name": "my-app" }, "environments": ["production", "preview", "development"], "envPulled": true, "warnings": [] }All top-level keys are always present —
billingPlanandprojectarenull(not omitted) when absent.Design decisions
integrationsubcommands (list,open,balance,remove,discover)warningsarray--format— only the auto-provision code path supports JSON; the legacy flow errors with a clear messagebuildSSOLink(), no extra API calls neededENV_PULL_FAILED_MESSAGEused by bothpostProvisionSetupand the JSON warnings builderTest plan
--format=jsonoutputs valid JSON to stdout on success (no project context)project: nullwhen no project is linkedssoUrl.integrationandssoUrl.resource--format=xml→ error, exit code 1--format, behavior unchanged (no JSON on stdout)--formatfiltered from help when auto-provision FF is offformatDynamicExamplescoverage test)🤖 Generated with Claude Code