# Create Release Pr

> Create a version-bump release PR for the TypeScript SDK based on latest remote main, with a semver suggestion derived from changes since the last release.

- Skill: `twilio/create-release-pr` (Agent Skill)
- Install (CLI): `npx skillmds add twilio/create-release-pr`
- Raw SKILL.md: https://api.skillmd.com/api/skills/twilio/create-release-pr/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: twilio (https://skillmd.com/u/twilio)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/twilio/create-release-pr

---


# Create a Release PR (TypeScript SDK)

This skill creates a version-bump PR for `twilio-agent-connect` (the TypeScript SDK).
It branches off the **latest remote `main`**, bumps the version in `package.json`,
runs `npm install` to update `package-lock.json`, and opens a PR.

The version follows [semantic versioning](https://semver.org/). The skill inspects
commits since the last release tag, **suggests** a bump, and asks the user to confirm
or override it.

## What gets changed

A version bump touches exactly two files (the runtime `User-Agent` version is read
dynamically from `package.json` at `packages/core/src/clients/base.ts`, so it does not
need editing):

- `package.json` — the top-level `"version"` field (line ~3)
- `package-lock.json` — the root package version entries (regenerated by `npm install`)

> Note: this is a single-version monorepo — the `packages/{core,tools,server}` directories
> have **no** individual `package.json` files, so there is only one version to bump.

## Arguments

`$ARGUMENTS` (the full argument string):

1. **Explicit version** (optional): a semver string like `2.1.0`. If present, skip the
   suggestion logic and use this version (still confirm with the user).
2. **`--no-pr`** (optional): commit and push the change on a branch, but don't open the PR —
   leave it ready for the user to open manually.

## Workflow

### Phase 0: Preflight

Verify `gh` is installed and authenticated against this repo, and that `npm` is available:

```bash
gh repo view twilio/twilio-agent-connect-typescript --json name --jq '.name'
npm --version
```

If `gh` fails for any reason (not installed, not authenticated, no access, network), **STOP**
and tell the user to run `gh auth status` / `gh auth login`. If `npm` is missing, **STOP** and
tell the user this skill requires `npm`.

### Phase 1: Sync to latest remote main and check the working tree

The release branch **must** be based on the latest remote `main`. Do not rebase or reset the
user's current branch — the branch is cut fresh from `origin/main` in Phase 3.

```bash
cd "$(git rev-parse --show-toplevel)"
git fetch origin
git status --porcelain
```

**If `git status --porcelain` is non-empty** (uncommitted changes exist), warn the user — the
release branch is cut from `origin/main`, so their uncommitted work won't be included but will
remain on their current branch. Use `AskUserQuestion` ("Continue?" / "Abort"); on abort, STOP
and confirm nothing was changed.

> Exception: if any uncommitted change touches `package.json` or `package-lock.json`, **STOP
> regardless** and ask the user to commit or stash those two files first — the skill needs a
> clean base for them.

### Phase 2: Determine current version and changes since last release

```bash
# Current version
grep -E '^  "version"' package.json | head -1

# Latest release tag (vMAJOR.MINOR.PATCH)
git tag --sort=-creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1

# Commits since that tag (use the tag from above; if no tag exists, use the full history)
git log --oneline <LAST_TAG>..origin/main

# The actual code changes since that tag — this is the source of truth for the bump
git diff --stat <LAST_TAG>..origin/main
git diff <LAST_TAG>..origin/main -- packages/ src/
```

### Phase 3: Suggest a semver bump and confirm

Decide the bump from **what the code actually changed**, not from commit-message prefixes
(this repo doesn't enforce Conventional Commits, so subjects are an unreliable signal). Read
the diff from Phase 2 — focusing on the public API surface under `packages/*/src/` and the
root `src/index.ts` re-exports (exported classes, functions, Zod schema fields, function
signatures, defaults) — and pick the level by semver intent:

- **MAJOR** (`X+1.0.0`): a backward-incompatible change to the public API — removed/renamed
  exports, changed signatures or required params, removed/renamed schema fields, changed
  defaults or behavior existing callers depend on.
- **MINOR** (`X.Y+1.0`): backward-compatible new capability — new exported API, new optional
  params/fields, new channels/adapters/tools.
- **PATCH** (`X.Y.Z+1`): no public-API surface change — bug fixes, internal refactors, docs,
  examples, tests, CI/build only.

Commit subjects are a useful hint to skim first, but when a subject and the diff disagree,
**trust the diff**. If the diff is large, read the parts touching exported symbols rather than
implementation internals.

Pre-1.0 caveat: not applicable here (current series is ≥1.0.0), so use standard semver.

**If an explicit version was passed in `$ARGUMENTS`**, skip this analysis and use it as the
suggestion (but still confirm).

Present the decision with `AskUserQuestion`. State the suggested level and a one-line
rationale grounded in the code change (e.g. "added a new optional voice config field, no
breaking changes → MINOR"):

- Question: "Current version is `X.Y.Z`. Since `vX.Y.Z`: <one-line rationale grounded in the
  diff>. Suggested next version is **`A.B.C`** (<level>). Which version should this release
  use?"
- Options (first = recommended):
  - `A.B.C` — "<suggested level> (Recommended)"
  - the other two semver candidates (e.g. the patch and major alternatives)

  The user can pick one, or choose "Other" to type any custom semver string.

After selection, validate the chosen version:

- It must match `^[0-9]+\.[0-9]+\.[0-9]+$` (allow a pre-release/build suffix only if the
  user explicitly typed one).
- It must be **strictly greater** than the current version. If not, show the conflict and
  re-ask rather than proceeding.

Let `NEW_VERSION` be the confirmed value. Create the release branch from latest remote main:

```bash
git checkout -b "release/bump-v${NEW_VERSION}" origin/main
```

### Phase 4: Apply the bump

1. Edit `package.json` — change the single top-level `"version": "..."` line (line ~3) to
   `NEW_VERSION`. Use `Edit` to replace only that line; do not touch any `"version"`-like
   fields inside `dependencies`/`devDependencies` or nested config.

2. Regenerate the lockfile:

```bash
npm install
```

3. Confirm only the two expected files changed and the lock updated correctly:

```bash
git status --porcelain                            # expect only package.json and package-lock.json
git diff --unified=0 package.json package-lock.json  # sanity-check the version strings
```

If anything other than `package.json` and `package-lock.json` is modified, STOP and show the
user the diff before continuing. (If `npm install` also refreshed unrelated transitive deps in
the lockfile, note it for the user but it is generally fine.)

### Phase 5: Verify

Run the repo's checks to make sure the bump didn't break anything:

```bash
npm run build && npm run lint && npm run typecheck && npm test
```

If any check fails, STOP, show the failure, and ask the user how to proceed. Do not open a PR
on a failing tree.

### Phase 6: Commit, push, and open the PR

**Stage explicitly by path** (never `git add -A/./-u`):

```bash
git add package.json package-lock.json
git status                          # confirm only these two are staged
```

Commit (match the established subject style — see `git log`, which uses a terse `vX.Y.Z`
subject for release bumps):

```bash
git commit -m "$(cat <<'EOF'
vNEW_VERSION

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EOF
)"
```

(Substitute the real `NEW_VERSION` before running, e.g. `v2.1.0`.)

```bash
git push -u origin "release/bump-v${NEW_VERSION}"
```

**If `--no-pr` was passed:** STOP here. Tell the user the branch is pushed and ready, and
print the `gh pr create` command they can run, plus a compare URL.

**Otherwise**, read the PR template and open the PR:

1. Read `.github/PULL_REQUEST_TEMPLATE.md` and fill it in:
   - **Summary**: "Bump version `X.Y.Z` → `NEW_VERSION`." Include a short bullet list of the
     notable changes since the last release (grouped: Features / Fixes / Other), derived from
     the Phase 2 commit log.
   - **Type of Change**: check the box that best fits the aggregate release (typically
     **New feature** for a MINOR, **Breaking change** for a MAJOR, **Bug fix** for a PATCH).
   - **Checklist**: check what applies (tests pass via the Phase 5 checks).
   - **SDK Parity**: check "Change is TypeScript-specific (no Python update needed)" — a
     version bump is TypeScript-specific.

2. Create the PR:

```bash
gh pr create \
  --base main \
  --title "vNEW_VERSION" \
  --body "<filled-in PR template>"
```

### Phase 7: Report

Print a short summary:

```
# Release PR

- Previous version: X.Y.Z
- New version:      NEW_VERSION   (<bump level>)
- Branch:           release/bump-vNEW_VERSION  (based on origin/main @ <short sha>)
- Checks:           build + lint + typecheck + test passed
- PR:               <url, or "not created (--no-pr)">
```

