بنقرة واحدة
qv-sdk-changelog
// Generate changelogs for SDK pod packages using tag-based GitFlow. Use when preparing a release, generating changelog, or creating CHANGELOG_LLM.md.
// Generate changelogs for SDK pod packages using tag-based GitFlow. Use when preparing a release, generating changelog, or creating CHANGELOG_LLM.md.
Plan and run local PR validation for tetherto/qvac PRs. Reuses the shared PR worktree, discovers touched packages and package.json scripts, recommends a test tier, and analyzes results. Use when testing a PR or invoking /qv-pr-test.
Plans and scaffolds e2e tests in packages/sdk/e2e for a new or changed public SDK API. Use when adding or modifying SDK functionality that is exposed to consumers. Enforces happy / sad / error coverage, deterministic model-output assertions, mobile/desktop placement, smoke-suite selection, and local validation with run:local.
Catalog of all repo qv-* custom skills with one-line purpose and when-to-use. Use when the user asks what skills exist, which skill to use, how to invoke a skill, or invokes /qv-skill-list.
Release a package to NPM. Validates version bump, changelog, creates release branch, monitors CI, verifies publish.
Diagnose why CI checks are not running on a PR and/or why a PR cannot be merged, by cross-referencing the live PR state (via gh CLI) against the repo's labels, teams, CODEOWNERS, label-gate trust model, and tier-based approval rules. Read-only by default — proposes labels / re-review comments / unblock actions in plan-then-apply mode. Use when a developer asks "why aren't my checks running", "why can't I merge", "what's blocking my PR", or invokes /qv-devops-why-my-pr-not with a PR URL.
Generate changelog entries for a target add-on package. Use when preparing a new release.
| name | qv-sdk-changelog |
| description | Generate changelogs for SDK pod packages using tag-based GitFlow. Use when preparing a release, generating changelog, or creating CHANGELOG_LLM.md. |
Generate changelogs for SDK pod packages following the monorepo GitFlow.
Applies to SDK pod packages as defined in .cursor/rules/sdk/sdk-pod-packages.mdc.
Use when:
/qv-sdk-changelogEvery step is mandatory. Do not ask the user whether to do CHANGELOG_LLM.md or
NOTICE — they are part of this skill and always run.
If the user doesn't specify, ask which SDK pod package they want to generate a changelog for.
Tags live on the upstream remote (tetherto/qvac), not the contributor's fork.
The script fetches from upstream first, falling back to origin.
Run git tag --list "<package>-v*" --sort=-v:refname to check for existing version tags.
package.json version:
.0, e.g. 0.9.0): uses the latest .0 tag as base (e.g. sdk-v0.8.0), skipping patch tags0.8.4): uses the absolute latest tag as base (e.g. sdk-v0.8.3)--base-commit and --base-version (migration scenario)Why this matters: patches ship on separate release branches and get backmerged into main.
Using the latest patch tag as base for a minor release would miss all PRs that landed on main
between the previous minor release and the last backmerge. The correct base for a minor release
is the previous minor's .0 tag.
All SDK pod packages use the same command:
node scripts/sdk/generate-changelog-sdk-pod.cjs --package=<name>
With migration flags:
node scripts/sdk/generate-changelog-sdk-pod.cjs --package=<name> --base-commit=<sha> --base-version=<version>
The script automatically excludes:
[skiplog].Backmerge or Merge release …).
Backmerges merge a release branch back into main; their content is already
documented in the release branch's own changelog, so listing them here is noise.For [mod] PRs, the script extracts the Added/Updated/Removed model lists
from the PR body and renders them as indented continuation lines beneath the
bullet in CHANGELOG.md (each section on its own line — never inline as one
giant row). The same filtered lists are written to models.md.
The extractor applies two policies (in this order):
*_LEX, *_VOCAB, *_DATA, *_METADATA) and any free-form
description containing the word "companion". Only first-class models reach
the changelog.(N entries) /
(N entries — short note) decorations are removed from the displayed
text — readers can follow the models.md link for exact counts.After both filters, each section is trimmed to MAX_INLINE_MODELS (currently
5) entries, with (and N more) for the remainder. Example:
- Regenerate model registry. (see PR [#123](...)) - See [model changes](./models.md)
Added: NMT_Q0F16, NMT_Q4_0 (and 12 more)
Removed: MARIAN_OPUS_*
If after filtering a section is empty, it's omitted. If all sections are empty the bullet emits with no continuation lines.
When writing the human-readable CHANGELOG_LLM.md (Step 4), apply the same
"no informational value" rule manually: skip backmerges, automated bumps, and any
entry whose subject would just repeat what a previous release already said. For
the Models section, mirror the script's policy — keep it concise in the body
(highlight the most notable adds/removes) and defer the full constant list to
the ### Added / ### Removed blocks at the bottom.
Always run this step. Do not ask the user — it's part of the skill.
After raw changelog files exist, generate the human-readable version at
packages/<package>/changelog/<version>/CHANGELOG_LLM.md.
See references/changelog-llm-format.md for the format guide.
After writing the file, re-run the raw generator (or rebuild the root aggregate) so
packages/<package>/CHANGELOG.md picks up the new CHANGELOG_LLM.md (the aggregator
prefers it over CHANGELOG.md). Easiest way: re-run the script from Step 3 — it's idempotent.
Downstream rendering note: the docs site reads CHANGELOG_LLM.md
verbatim and inlines it under a ### @qvac/<pkg> subsection of the
minor series page (one permanent v<X.Y>.x.mdx per minor line — see
docs/website/docs-workflow.md). Each headline you write becomes a
section header on the public docs site (with two levels of demotion to
fit the nesting), so phrase them as standalone reader-facing prose, not
internal categories. Keep headings emoji-free (e.g. ## Breaking Changes, not ## 💥 Breaking Changes) — emoji prefixes leak verbatim
into the public headers; the only allowed emoji is the 📦 **NPM:**
line. See the format guide for the full rule.
announcement-post.txt (mandatory)Always run this step after Step 4. It produces a Slack-ready copy-paste post at
packages/<package>/changelog/<version>/announcement-post.txt.
The file is gitignored (packages/*/changelog/*/announcement-post.txt) — it's a
local working artifact, not a committed deliverable. Never git add it.
node scripts/sdk/generate-changelog-sdk-pod.cjs --package=<name> --generate-announcement-post
The script emits the short Slack template — header + three links + optional breaking-changes block + footer. Per-section bullet lists are intentionally omitted; readers follow the full-changelog link for the detail.
Layout:
:qvac: SDK <version> :rocket: NPM Public release header.:warning: Breaking Changes section with link to breaking.md — emitted
only when breaking.md exists in the version folder (i.e. at least one PR
carries the [bc] tag). Detected by file presence, not by parsing
CHANGELOG.md.Thanks to everyone on QVAC team :green_heart: :qvac: :green_heart:.If the post needs hand-tuning (e.g. a custom note for a specific release), edit the file directly. It's gitignored, so changes won't pollute the diff.
After Step 5 completes, run notice-generate for the same --package to ensure
its NOTICE file reflects any dependency changes in the release:
source .env
node .cursor/skills/qv-notice-generate/scripts/generate-notice.js <package-name>
Do NOT commit the announcement post (gitignored) and let the user review the rest before committing.
See .cursor/skills/qv-notice-generate/SKILL.md for full details.
| Flag | Required | Description |
|---|---|---|
--package | Yes | Package name (e.g., sdk) |
--base-commit | No | Initial commit SHA for migration (overrides tag lookup) |
--base-version | No | Version label for base commit (display only) |
--release-type | No | minor or patch (auto-detected from package.json version) |
--dry-run | No | Preview output without writing files |
--update-root-changelog | No | Rebuild only the root aggregate packages/<pkg>/CHANGELOG.md |
--generate-announcement-post | No | Generate announcement-post.txt for the package's current version |
--version | No | Override version when used with --generate-announcement-post |
Generates changelog files in packages/<package>/changelog/<version>/:
CHANGELOG.md - Main changelogbreaking.md - Breaking changes detail (if [bc] PRs)api.md - API changes detail (if [api] PRs)models.md - Model changes (if [mod] PRs)CHANGELOG_LLM.md - Human-readable version (always generated, see Step 4)announcement-post.txt - Slack copy-paste post (always generated, see Step 5,
gitignored — never commit)Additionally:
packages/<package>/CHANGELOG.md – Aggregated changelog containing all versions (newest → oldest), preferring CHANGELOG_LLM.md (human-readable) from each version folder when available, falling back to CHANGELOG.mdTags follow the pattern: <package>-v<x.y.z> and are created on upstream (not the fork).
Examples:
sdk-v0.8.0 (minor — used as base for next minor release)sdk-v0.8.1 (patch — used as base for next patch release)rag-v2.0.0Before completing:
--base-commit).cursor/rules/sdk/sdk-pod-packages.mdc/gitflow.md.cursor/rules/sdk/commit-and-pr-format.mdc.cursor/skills/qv-notice-generate/SKILL.md