Skip to content

feat(cli): non-interactive mode for add + new changed command - #1890

Closed
brunorodmoreira wants to merge 7 commits into
changesets:mainfrom
brunorodmoreira:feat/non-interactive-add-and-changed-command
Closed

feat(cli): non-interactive mode for add + new changed command#1890
brunorodmoreira wants to merge 7 commits into
changesets:mainfrom
brunorodmoreira:feat/non-interactive-add-and-changed-command

Conversation

@brunorodmoreira

@brunorodmoreira brunorodmoreira commented Mar 16, 2026

Copy link
Copy Markdown

Summary

Adds non-interactive mode to changeset add and introduces a new changeset changed command, enabling AI agents, CI pipelines, and automation scripts to create changesets without interactive prompts.

Motivation

The current changeset add flow requires interactive input for package selection, bump type, and summary — making it unusable for AI coding assistants (Claude Code, Cursor, GitHub Copilot, etc.), CI pipelines, and automation scripts. This has been requested across multiple issues (#979, #1604, Discussion #1118).

As AI-assisted development becomes the norm, tools like changesets need a programmatic interface so agents can handle the full commit-and-changeset workflow autonomously.

New flags for changeset add

Flag Alias Type Description
--package -p string (repeatable) Package name to include in the changeset. Use multiple times for multiple packages
--type -t patch|minor|major Bump type applied to all selected packages
--all boolean Auto-select all changed packages (git-aware)

Non-interactive mode activates when --package (or --all) and --message are both provided. When any required input is missing, it gracefully falls back to the interactive flow.

New command: changeset changed

changeset changed [--since <branch>] [--json]

Lists packages that have changed since the base branch — the same detection logic used in the first step of the interactive add flow, now exposed as a standalone command. This enables a two-step workflow for AI agents: discover → create.

Manual Testing

Tested against a real monorepo (private, 27+ packages across apps/, packages/, libs/).

changeset changed

$ changeset changed
🦋  Changed packages since "develop":
🦋  @ollie-shop/functions
🦋  hub
$ changeset changed --json
🦋  [
🦋    {
🦋      "name": "@ollie-shop/functions",
🦋      "dir": "/path/to/packages/functions"
🦋    },
🦋    {
🦋      "name": "hub",
🦋      "dir": "/path/to/apps/hub"
🦋    }
🦋  ]

Non-interactive add — single package

$ changeset add --package @ollie-shop/functions --type patch -m "test non-interactive add"
🦋  === Summary of changesets ===
🦋  patch:  @ollie-shop/functions
🦋  Changeset added and committed
🦋  info /path/to/.changeset/tiny-radios-hide.md

Non-interactive add — multiple packages

$ changeset add --package @ollie-shop/functions --package hub --type minor -m "test multiple packages"
🦋  === Summary of changesets ===
🦋  minor:  @ollie-shop/functions, hub
🦋  Changeset added and committed
🦋  info /path/to/.changeset/soft-nights-make.md

Error: unknown package

$ changeset add --package nonexistent --type patch -m "should fail"
🦋  error The package "nonexistent" was not found in the project. Available packages: admin, builder, ...

Error: missing --type

$ changeset add --package hub -m "no type"
🦋  error --type is required when using non-interactive mode

AI Agent Workflow Example

# Step 1: Agent discovers what changed
CHANGED=$(changeset changed --since main --json)

# Step 2: Agent reasons about bump types based on commit history/diff

# Step 3: Agent creates the changeset
changeset add \
  --package @acme/core \
  --package @acme/cli \
  --type minor \
  -m "Add streaming support to core and CLI"

Test Plan

  • All existing add command tests pass (no regressions)
  • New tests in run.test.ts for --package flag normalization (single → array, multiple, undefined, --all passthrough)
  • Full CLI test suite passes
  • Manual end-to-end testing against real monorepo (ollie-shop, 27+ packages)

Review Changes Applied

Addressed all feedback from @Andarist:

  1. Flattened nested describe blocks — moved non-interactive tests from add/__tests__/add.ts to run.test.ts
  2. Removed colon syntax (pkg:type) — sticking to --type for simplicity
  3. Renamed --packages--package (singular, repeatable via mri)
  4. Normalized --package early to string[] in run.ts
  5. Changed errorlog for "no changed packages" (valid state, not an error)
  6. Added header with resolved since value before listing changed packages

Closes #979
Closes #1604

Enable AI agents, CI pipelines, and scripts to create changesets without
interactive prompts by providing all required inputs via CLI flags.

New flags for `changeset add`:
- `--packages` (`-p`): specify packages with optional bump type (e.g. `pkg:minor`)
- `--type` (`-t`): default bump type for all packages (`patch|minor|major`)
- `--all`: auto-select all changed packages (git-aware)

New command `changeset changed`:
- Lists packages changed since base branch (one per line)
- `--json` flag for machine-readable output
- `--since` flag for custom git ref

Non-interactive mode activates when `--packages` (or `--all`) and `--message`
are both provided. Falls back to interactive mode otherwise.

Closes changesets#979
Closes changesets#1604
@changeset-bot

changeset-bot Bot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e443d86

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@changesets/cli Minor

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

@codecov

codecov Bot commented Mar 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 43.75000% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.13%. Comparing base (96ca062) to head (e443d86).

Files with missing lines Patch % Lines
packages/cli/src/commands/add/index.ts 13.51% 32 Missing ⚠️
packages/cli/src/run.ts 71.42% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1890      +/-   ##
==========================================
- Coverage   84.24%   83.13%   -1.12%     
==========================================
  Files          56       57       +1     
  Lines        2419     2479      +60     
  Branches      729      747      +18     
==========================================
+ Hits         2038     2061      +23     
- Misses        375      412      +37     
  Partials        6        6              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread packages/cli/src/commands/add/__tests__/add.ts Outdated
Comment thread packages/cli/src/commands/add/__tests__/add.ts Outdated
Comment thread packages/cli/src/index.ts Outdated
Comment thread packages/cli/src/types.ts Outdated
Comment thread packages/cli/src/commands/changed/index.ts Outdated
Comment thread packages/cli/src/commands/changed/index.ts
…nged command

- Rename --packages to --package (singular, repeatable via mri)
- Remove colon syntax (pkg:type), stick to --type only
- Normalize --package flag early to string[] in run.ts
- Move non-interactive tests from nested describe in add.ts to run.test.ts
- Use log instead of error for "no changed packages" (valid state)
- Add header with resolved since value before listing changed packages
- Update changed command test to expect log instead of error
- Run prettier on all affected files
Integrate upstream's dynamic COMMAND_HELP rendering with our new
`changed` command and additional `add` flags.
Integrate upstream's refactoring (aliases extraction, COMMAND_HELP
moved to help.ts, validateCommandFlags) with our non-interactive
add flags and changed command.
@samdcoding

Copy link
Copy Markdown

@brunorodmoreira would love to see this land 🥇

@beeequeue

Copy link
Copy Markdown
Member

this PR makes two separate modifications, non-interactive mode and a new command. could these be split up into separate PRs?

we have also made major changes to the CLI code in the next (v3) branch, which means upstreaming this would be quite difficult.

with these two points in mind, could you split the PR and base it on next instead?


i am also not sure about having a changed command, as it's something that could be handled by package managers or monorepo tooling instead.

for example, pnpm already supports filtering with git:
pnpm ls --json --depth -1 --filter '...[git ref]' returns all packages that have changed along with their dependents, see Filtering

this supports everything pnpm related already, something Changesets fails in some regards (#1707)

@brunorodmoreira

Copy link
Copy Markdown
Author

Surething @beeequeue . I will rework it then and let you know.

@beeequeue

beeequeue commented Jun 24, 2026

Copy link
Copy Markdown
Member

closing this based on previous comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] add non-interactive mode for changeset add [feat] Support non-interactive mode / command way to add changelog

4 participants