The vcad changelog lives in changelog/entries/ at the repository root, with one JSON file per entry. A small aggregator (scripts/build-changelog.mjs) rolls them up into a generated CHANGELOG.json (gitignored) that the docs site, release tooling, and the app's "What's New" display read. One file per entry means concurrent PRs never collide on the changelog.
Adding an Entry
Drop a new file in changelog/entries/ named <id>.json, where the id is the same as the entry's id field:
changelog/entries/2025-03-15-fillet-chamfer.json
The aggregator runs automatically as a postinstall step (and again as part of @vcad/core's build), so the rolled-up CHANGELOG.json stays current without any manual step. You can also rebuild it explicitly:
npm run changelog:build
Entry Format
Each file is a single JSON object with these fields:
{
"id": "2025-03-15-fillet-chamfer",
"version": "0.4.0",
"date": "2025-03-15",
"category": "feat",
"title": "Fillet and chamfer operations",
"summary": "Add rolling-ball fillets and chamfers for plane-plane and plane-cylinder edge types.",
"features": ["fillet", "chamfer", "modeling"],
"mcpTools": []
}
id is a unique slug in YYYY-MM-DD-short-description format. It must be globally unique across all entries.
version is the current version from package.json at the time of the change.
date is the ISO 8601 date when the change was made.
category is one of five values: feat for new user-facing features, fix for bug fixes, breaking for breaking changes (API, file format, behavior), perf for significant performance improvements, and docs for major documentation changes.
title is a short description, maximum 60 characters. Write it as a noun phrase or imperative statement: "Fillet and chamfer operations", "Fix boolean winding on cylinder caps".
summary is a single sentence, maximum 200 characters, providing slightly more context than the title.
features is an array of relevant tags for filtering and grouping: ["boolean", "kernel"], ["sketch", "constraints"], ["physics", "mcp"], etc.
mcpTools is an array of MCP tool names if the change adds or modifies MCP tools: ["create_cad_document", "export_cad"]. Empty array if not applicable.
When to Add Entries
Add a changelog entry when:
- Adding a user-facing feature (new primitive, new operation, new UI component)
- Fixing a user-facing bug (incorrect rendering, wrong export output, crash)
- Making a breaking change (IR format change, API signature change, behavior change)
- Achieving a significant performance improvement (measurable speedup that users will notice)
Skip changelog entries for:
- Internal refactors that don't change behavior
- Test-only changes
- Documentation updates (unless they represent a major new section)
- Dependency bumps
- Code formatting changes
Order is derived from each entry's date and id field — the aggregator sorts newest first automatically. You don't have to think about placement; just give the file a date-prefixed id.
Schema Validation
The file /changelog.schema.json in the repository root defines the JSON Schema for the changelog. The schema validates:
- Required fields are present (id, version, date, category, title, summary, features)
- Category is one of the allowed values
- Title length does not exceed 60 characters
- Summary length does not exceed 200 characters
- Date is in ISO 8601 format
- Features and mcpTools are arrays of strings
CI can validate each entry against this schema to catch formatting errors before merge. You can also validate locally with any JSON Schema tool:
npm run changelog:build
npx ajv-cli validate -s changelog.schema.json -d CHANGELOG.json
Example Entries
A feature entry:
{
"id": "2025-04-01-sketch-constraints",
"version": "0.5.0",
"date": "2025-04-01",
"category": "feat",
"title": "2D sketch constraint solver",
"summary": "Levenberg-Marquardt solver with 12 constraint types for fully parametric sketches.",
"features": ["sketch", "constraints", "parametric"],
"mcpTools": []
}
A bug fix entry:
{
"id": "2025-04-10-boolean-winding",
"version": "0.5.1",
"date": "2025-04-10",
"category": "fix",
"title": "Fix inverted normals after boolean difference",
"summary": "Cylinder cap faces at z=max now face outward after boolean subtraction.",
"features": ["boolean", "kernel", "tessellation"],
"mcpTools": []
}
A breaking change entry:
{
"id": "2025-05-01-ir-v2",
"version": "0.6.0",
"date": "2025-05-01",
"category": "breaking",
"title": "IR format version 0.2",
"summary": "Node IDs are now strings instead of numbers. Existing .vcad files need migration.",
"features": ["ir", "format"],
"mcpTools": ["create_cad_document"]
}
Related Pages
The Contributing Guide page covers the full development workflow. The System Overview page maps the codebase.