From dd796dbd6e48d57135b96c91a1d83195f1fb3a12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 03:31:19 +0000 Subject: [PATCH] chore: version packages --- .changeset/build-watch-incremental.md | 63 ----------- .changeset/cell-filter-and-oneline.md | 45 -------- .changeset/cli-citty-consola.md | 12 -- .changeset/philosophy-audit-fixes.md | 29 ----- examples/basic/CHANGELOG.md | 15 +++ examples/basic/package.json | 2 +- examples/nextjs/CHANGELOG.md | 14 +++ examples/nextjs/package.json | 2 +- packages/cli/CHANGELOG.md | 98 ++++++++++++++++ packages/cli/package.json | 2 +- packages/core/CHANGELOG.md | 121 ++++++++++++++++++++ packages/core/package.json | 2 +- packages/engine-nunjucks/CHANGELOG.md | 126 +++++++++++++++++++++ packages/engine-nunjucks/package.json | 2 +- packages/extractor-typescript/CHANGELOG.md | 66 +++++++++++ packages/extractor-typescript/package.json | 2 +- packages/language-server/CHANGELOG.md | 66 +++++++++++ packages/language-server/package.json | 2 +- packages/profile-markdown/CHANGELOG.md | 66 +++++++++++ packages/profile-markdown/package.json | 2 +- packages/profile-mintlify/CHANGELOG.md | 66 +++++++++++ packages/profile-mintlify/package.json | 2 +- 22 files changed, 647 insertions(+), 158 deletions(-) delete mode 100644 .changeset/build-watch-incremental.md delete mode 100644 .changeset/cell-filter-and-oneline.md delete mode 100644 .changeset/cli-citty-consola.md delete mode 100644 .changeset/philosophy-audit-fixes.md diff --git a/.changeset/build-watch-incremental.md b/.changeset/build-watch-incremental.md deleted file mode 100644 index 6c0f71f..0000000 --- a/.changeset/build-watch-incremental.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -"@vellum-docs/cli": minor -"@vellum-docs/core": minor -"@vellum-docs/engine-nunjucks": minor ---- - -Add `vellum build --watch` with per-template invalidation - -Edit a template or a source file and Vellum re-renders only the output files affected by the change. A docs project that wires `vellum build --watch` alongside the host's dev server (Next.js, Mintlify, etc.) no longer needs a restart loop to see TSDoc edits. - -```sh -vellum build --watch -``` - -### How invalidation works - -Templates are instrumented while rendering. The `symbol()`, `symbols()`, and `module()` globals record what each `.vel` file actually read: - -- `symbol(id)` - the looked-up `SymbolId`, -- `module(path)` - the module path, -- `symbols(query)` - the verbatim query *and* the resulting ids. - -On a source-file change, Vellum diffs the file's old vs new symbols (source-position-insensitive content hash) and re-renders templates whose recorded reads intersect the diff. Added symbols are re-matched against each template's prior queries so a new `symbols({ tag: 'foo' })` result triggers the right renders. - -Template edits re-render only that template. Config changes tear down the watcher and re-prime. Render and extract errors log and keep the previous output on disk - the watcher stays alive. - -### API changes (minor - pre-1.0) - -**`TemplateEngine.render` returns `RenderResult`**, not `string`. Custom engines update the return shape: - -```ts -// before -async render(source, ctx): Promise { ... } - -// after -async render(source, ctx): Promise { - return { output } - // or { output, reads } when ctx.reads was supplied -} -``` - -**`SymbolIndex` gains `symbolsByFile` and `removeByFile`.** Custom index implementations need both. `InMemorySymbolIndex` now tracks per-file provenance via `Symbol.source.file`. - -**`matchesQuery(sym, query)`** is exported from `@vellum-docs/core` - the exact predicate `InMemorySymbolIndex.symbols()` uses, reusable by tooling that needs to test a single symbol against a query. - -### New exports (`@vellum-docs/core`) - -- `TemplateReads`, `createTemplateReads()` -- `SymbolDiff`, `diffSymbols`, `hashSymbol`, `mergeDiffs`, `emptyDiff`, `isEmptyDiff` -- `DependencyGraph` -- `Vellum.extractLanguage`, `Vellum.renderTemplate`, `Vellum.listTemplates` - -### New exports (`@vellum-docs/cli`) - -- `runWatch`, `WatchCommandOptions` - -### Watcher details - -File watching uses [chokidar](https://github.com/paulmillr/chokidar) v4 with Nuxt-style granular filtering: `node_modules`, `.git`, `.turbo`, `dist`, `build`, `coverage`, and the resolved `outDir` are ignored anywhere in the tree, even if a user's `sources[lang].include` would otherwise cover them. Events are debounced 100ms; `awaitWriteFinish` handles editor save races. - -### Known tradeoff - -Per-file TS extraction isn't meaningful in isolation (cross-file type graph), so `extractLanguage` re-runs the extractor over the whole program on each batch. Invalidation still narrows the *render* set - which is what dominates latency for a typical docs project - but we don't yet skip extraction for unchanged files beyond the existing content-hash cache. diff --git a/.changeset/cell-filter-and-oneline.md b/.changeset/cell-filter-and-oneline.md deleted file mode 100644 index b94c277..0000000 --- a/.changeset/cell-filter-and-oneline.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -"@vellum-docs/core": patch -"@vellum-docs/extractor-typescript": patch -"@vellum-docs/engine-nunjucks": patch -"@vellum-docs/profile-markdown": patch -"@vellum-docs/profile-mintlify": patch -"@vellum-docs/language-server": patch ---- - -Add `cell` filter + `TypeString.oneline` for cell-safe rendering - -Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: - -```njk -{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} -``` - -Two additions collapse that: - -**`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. - -**`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. - -Before: - -```njk -| `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | -``` - -After: - -```njk -| `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | -``` - -### Schema additions (additive) - -- `TypeString.oneline?: string` -- `RendererProfile.cell(value: string, ctx: RenderContext): string` - -Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. - -### Out of scope - -`jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. diff --git a/.changeset/cli-citty-consola.md b/.changeset/cli-citty-consola.md deleted file mode 100644 index 8e36468..0000000 --- a/.changeset/cli-citty-consola.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@vellum-docs/cli": patch ---- - -Refactor CLI to citty + consola - -Replaced hand-rolled argv parsing and `console.log` with two unjs libraries: - -- **[citty](https://github.com/unjs/citty)** drives argument parsing, subcommand routing, and help generation. `vellum --help` and `vellum build --help` now produce consistent typed output instead of a static string. -- **[consola](https://github.com/unjs/consola)** handles every user-facing log through a shared tagged logger. Output is color-coded by level (`success`, `info`, `warn`, `error`) with a uniform `[vellum]` prefix. - -No breaking CLI surface changes — `vellum build`, `--watch`, `--config`, `--cwd`, `--no-strict` all behave identically. `--no-strict` now comes from citty's boolean-negation convention instead of being parsed by hand. diff --git a/.changeset/philosophy-audit-fixes.md b/.changeset/philosophy-audit-fixes.md deleted file mode 100644 index dec851b..0000000 --- a/.changeset/philosophy-audit-fixes.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@vellum-docs/core": patch -"@vellum-docs/extractor-typescript": patch -"@vellum-docs/engine-nunjucks": patch -"@vellum-docs/cli": patch -"@vellum-docs/language-server": patch -"@vellum-docs/profile-markdown": patch -"@vellum-docs/profile-mintlify": patch ---- - -Philosophy audit fixes - strict-by-default, dead schema cleanup - -An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. - -**Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. - -Opt-out paths, for the rare cases where silent fallback is wanted during migration: - -- Config: `new NunjucksEngine({ strict: false })`. -- CLI: `vellum build --no-strict`. - -**This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. - -**Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): - -- `Symbol.signatureResolved?: string` - removed. -- `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. - -**Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. diff --git a/examples/basic/CHANGELOG.md b/examples/basic/CHANGELOG.md index 1ae41e6..34c9ee6 100644 --- a/examples/basic/CHANGELOG.md +++ b/examples/basic/CHANGELOG.md @@ -1,5 +1,20 @@ # vellum-example-basic +## 0.0.8 + +### Patch Changes + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [3840674] +- Updated dependencies [6503a35] + - @vellum-docs/cli@0.3.0 + - @vellum-docs/core@0.3.0 + - @vellum-docs/engine-nunjucks@0.3.0 + - @vellum-docs/extractor-typescript@0.3.0 + - @vellum-docs/profile-markdown@0.3.0 + - @vellum-docs/profile-mintlify@0.3.0 + ## 0.0.7 ### Patch Changes diff --git a/examples/basic/package.json b/examples/basic/package.json index c1f9236..ac69864 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -1,7 +1,7 @@ { "name": "vellum-example-basic", "type": "module", - "version": "0.0.7", + "version": "0.0.8", "private": true, "scripts": { "build": "vellum build" diff --git a/examples/nextjs/CHANGELOG.md b/examples/nextjs/CHANGELOG.md index d54d69d..cdad080 100644 --- a/examples/nextjs/CHANGELOG.md +++ b/examples/nextjs/CHANGELOG.md @@ -1,5 +1,19 @@ # vellum-example-nextjs +## 0.0.8 + +### Patch Changes + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [3840674] +- Updated dependencies [6503a35] + - @vellum-docs/cli@0.3.0 + - @vellum-docs/core@0.3.0 + - @vellum-docs/engine-nunjucks@0.3.0 + - @vellum-docs/extractor-typescript@0.3.0 + - @vellum-docs/profile-markdown@0.3.0 + ## 0.0.7 ### Patch Changes diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 940a661..67b32d2 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,7 +1,7 @@ { "name": "vellum-example-nextjs", "type": "module", - "version": "0.0.7", + "version": "0.0.8", "private": true, "scripts": { "docs:build": "vellum build", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 718126d..95e00a0 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,103 @@ # @vellum-docs/cli +## 0.3.0 + +### Minor Changes + +- 2a9986c: Add `vellum build --watch` with per-template invalidation + + Edit a template or a source file and Vellum re-renders only the output files affected by the change. A docs project that wires `vellum build --watch` alongside the host's dev server (Next.js, Mintlify, etc.) no longer needs a restart loop to see TSDoc edits. + + ```sh + vellum build --watch + ``` + + ### How invalidation works + + Templates are instrumented while rendering. The `symbol()`, `symbols()`, and `module()` globals record what each `.vel` file actually read: + + - `symbol(id)` - the looked-up `SymbolId`, + - `module(path)` - the module path, + - `symbols(query)` - the verbatim query _and_ the resulting ids. + + On a source-file change, Vellum diffs the file's old vs new symbols (source-position-insensitive content hash) and re-renders templates whose recorded reads intersect the diff. Added symbols are re-matched against each template's prior queries so a new `symbols({ tag: 'foo' })` result triggers the right renders. + + Template edits re-render only that template. Config changes tear down the watcher and re-prime. Render and extract errors log and keep the previous output on disk - the watcher stays alive. + + ### API changes (minor - pre-1.0) + + **`TemplateEngine.render` returns `RenderResult`**, not `string`. Custom engines update the return shape: + + ```ts + // before + async render(source, ctx): Promise { ... } + + // after + async render(source, ctx): Promise { + return { output } + // or { output, reads } when ctx.reads was supplied + } + ``` + + **`SymbolIndex` gains `symbolsByFile` and `removeByFile`.** Custom index implementations need both. `InMemorySymbolIndex` now tracks per-file provenance via `Symbol.source.file`. + + **`matchesQuery(sym, query)`** is exported from `@vellum-docs/core` - the exact predicate `InMemorySymbolIndex.symbols()` uses, reusable by tooling that needs to test a single symbol against a query. + + ### New exports (`@vellum-docs/core`) + + - `TemplateReads`, `createTemplateReads()` + - `SymbolDiff`, `diffSymbols`, `hashSymbol`, `mergeDiffs`, `emptyDiff`, `isEmptyDiff` + - `DependencyGraph` + - `Vellum.extractLanguage`, `Vellum.renderTemplate`, `Vellum.listTemplates` + + ### New exports (`@vellum-docs/cli`) + + - `runWatch`, `WatchCommandOptions` + + ### Watcher details + + File watching uses [chokidar](https://github.com/paulmillr/chokidar) v4 with Nuxt-style granular filtering: `node_modules`, `.git`, `.turbo`, `dist`, `build`, `coverage`, and the resolved `outDir` are ignored anywhere in the tree, even if a user's `sources[lang].include` would otherwise cover them. Events are debounced 100ms; `awaitWriteFinish` handles editor save races. + + ### Known tradeoff + + Per-file TS extraction isn't meaningful in isolation (cross-file type graph), so `extractLanguage` re-runs the extractor over the whole program on each batch. Invalidation still narrows the _render_ set - which is what dominates latency for a typical docs project - but we don't yet skip extraction for unchanged files beyond the existing content-hash cache. + +### Patch Changes + +- 3840674: Refactor CLI to citty + consola + + Replaced hand-rolled argv parsing and `console.log` with two unjs libraries: + + - **[citty](https://github.com/unjs/citty)** drives argument parsing, subcommand routing, and help generation. `vellum --help` and `vellum build --help` now produce consistent typed output instead of a static string. + - **[consola](https://github.com/unjs/consola)** handles every user-facing log through a shared tagged logger. Output is color-coded by level (`success`, `info`, `warn`, `error`) with a uniform `[vellum]` prefix. + + No breaking CLI surface changes — `vellum build`, `--watch`, `--config`, `--cwd`, `--no-strict` all behave identically. `--no-strict` now comes from citty's boolean-negation convention instead of being parsed by hand. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 66cb45a..ebd618c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/cli", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 2d185df..7b67ec9 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,126 @@ # @vellum-docs/core +## 0.3.0 + +### Minor Changes + +- 2a9986c: Add `vellum build --watch` with per-template invalidation + + Edit a template or a source file and Vellum re-renders only the output files affected by the change. A docs project that wires `vellum build --watch` alongside the host's dev server (Next.js, Mintlify, etc.) no longer needs a restart loop to see TSDoc edits. + + ```sh + vellum build --watch + ``` + + ### How invalidation works + + Templates are instrumented while rendering. The `symbol()`, `symbols()`, and `module()` globals record what each `.vel` file actually read: + + - `symbol(id)` - the looked-up `SymbolId`, + - `module(path)` - the module path, + - `symbols(query)` - the verbatim query _and_ the resulting ids. + + On a source-file change, Vellum diffs the file's old vs new symbols (source-position-insensitive content hash) and re-renders templates whose recorded reads intersect the diff. Added symbols are re-matched against each template's prior queries so a new `symbols({ tag: 'foo' })` result triggers the right renders. + + Template edits re-render only that template. Config changes tear down the watcher and re-prime. Render and extract errors log and keep the previous output on disk - the watcher stays alive. + + ### API changes (minor - pre-1.0) + + **`TemplateEngine.render` returns `RenderResult`**, not `string`. Custom engines update the return shape: + + ```ts + // before + async render(source, ctx): Promise { ... } + + // after + async render(source, ctx): Promise { + return { output } + // or { output, reads } when ctx.reads was supplied + } + ``` + + **`SymbolIndex` gains `symbolsByFile` and `removeByFile`.** Custom index implementations need both. `InMemorySymbolIndex` now tracks per-file provenance via `Symbol.source.file`. + + **`matchesQuery(sym, query)`** is exported from `@vellum-docs/core` - the exact predicate `InMemorySymbolIndex.symbols()` uses, reusable by tooling that needs to test a single symbol against a query. + + ### New exports (`@vellum-docs/core`) + + - `TemplateReads`, `createTemplateReads()` + - `SymbolDiff`, `diffSymbols`, `hashSymbol`, `mergeDiffs`, `emptyDiff`, `isEmptyDiff` + - `DependencyGraph` + - `Vellum.extractLanguage`, `Vellum.renderTemplate`, `Vellum.listTemplates` + + ### New exports (`@vellum-docs/cli`) + + - `runWatch`, `WatchCommandOptions` + + ### Watcher details + + File watching uses [chokidar](https://github.com/paulmillr/chokidar) v4 with Nuxt-style granular filtering: `node_modules`, `.git`, `.turbo`, `dist`, `build`, `coverage`, and the resolved `outDir` are ignored anywhere in the tree, even if a user's `sources[lang].include` would otherwise cover them. Events are debounced 100ms; `awaitWriteFinish` handles editor save races. + + ### Known tradeoff + + Per-file TS extraction isn't meaningful in isolation (cross-file type graph), so `extractLanguage` re-runs the extractor over the whole program on each batch. Invalidation still narrows the _render_ set - which is what dominates latency for a typical docs project - but we don't yet skip extraction for unchanged files beyond the existing content-hash cache. + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + ## 0.2.4 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index a064e6a..c1ddd76 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/core", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/engine-nunjucks/CHANGELOG.md b/packages/engine-nunjucks/CHANGELOG.md index 8a94389..9d49d71 100644 --- a/packages/engine-nunjucks/CHANGELOG.md +++ b/packages/engine-nunjucks/CHANGELOG.md @@ -1,5 +1,131 @@ # @vellum-docs/engine-nunjucks +## 0.3.0 + +### Minor Changes + +- 2a9986c: Add `vellum build --watch` with per-template invalidation + + Edit a template or a source file and Vellum re-renders only the output files affected by the change. A docs project that wires `vellum build --watch` alongside the host's dev server (Next.js, Mintlify, etc.) no longer needs a restart loop to see TSDoc edits. + + ```sh + vellum build --watch + ``` + + ### How invalidation works + + Templates are instrumented while rendering. The `symbol()`, `symbols()`, and `module()` globals record what each `.vel` file actually read: + + - `symbol(id)` - the looked-up `SymbolId`, + - `module(path)` - the module path, + - `symbols(query)` - the verbatim query _and_ the resulting ids. + + On a source-file change, Vellum diffs the file's old vs new symbols (source-position-insensitive content hash) and re-renders templates whose recorded reads intersect the diff. Added symbols are re-matched against each template's prior queries so a new `symbols({ tag: 'foo' })` result triggers the right renders. + + Template edits re-render only that template. Config changes tear down the watcher and re-prime. Render and extract errors log and keep the previous output on disk - the watcher stays alive. + + ### API changes (minor - pre-1.0) + + **`TemplateEngine.render` returns `RenderResult`**, not `string`. Custom engines update the return shape: + + ```ts + // before + async render(source, ctx): Promise { ... } + + // after + async render(source, ctx): Promise { + return { output } + // or { output, reads } when ctx.reads was supplied + } + ``` + + **`SymbolIndex` gains `symbolsByFile` and `removeByFile`.** Custom index implementations need both. `InMemorySymbolIndex` now tracks per-file provenance via `Symbol.source.file`. + + **`matchesQuery(sym, query)`** is exported from `@vellum-docs/core` - the exact predicate `InMemorySymbolIndex.symbols()` uses, reusable by tooling that needs to test a single symbol against a query. + + ### New exports (`@vellum-docs/core`) + + - `TemplateReads`, `createTemplateReads()` + - `SymbolDiff`, `diffSymbols`, `hashSymbol`, `mergeDiffs`, `emptyDiff`, `isEmptyDiff` + - `DependencyGraph` + - `Vellum.extractLanguage`, `Vellum.renderTemplate`, `Vellum.listTemplates` + + ### New exports (`@vellum-docs/cli`) + + - `runWatch`, `WatchCommandOptions` + + ### Watcher details + + File watching uses [chokidar](https://github.com/paulmillr/chokidar) v4 with Nuxt-style granular filtering: `node_modules`, `.git`, `.turbo`, `dist`, `build`, `coverage`, and the resolved `outDir` are ignored anywhere in the tree, even if a user's `sources[lang].include` would otherwise cover them. Events are debounced 100ms; `awaitWriteFinish` handles editor save races. + + ### Known tradeoff + + Per-file TS extraction isn't meaningful in isolation (cross-file type graph), so `extractLanguage` re-runs the extractor over the whole program on each batch. Invalidation still narrows the _render_ set - which is what dominates latency for a typical docs project - but we don't yet skip extraction for unchanged files beyond the existing content-hash cache. + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/engine-nunjucks/package.json b/packages/engine-nunjucks/package.json index 5a994e3..84ecf5d 100644 --- a/packages/engine-nunjucks/package.json +++ b/packages/engine-nunjucks/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/engine-nunjucks", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/extractor-typescript/CHANGELOG.md b/packages/extractor-typescript/CHANGELOG.md index 82ec66e..b731d85 100644 --- a/packages/extractor-typescript/CHANGELOG.md +++ b/packages/extractor-typescript/CHANGELOG.md @@ -1,5 +1,71 @@ # @vellum-docs/extractor-typescript +## 0.3.0 + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/extractor-typescript/package.json b/packages/extractor-typescript/package.json index 9ca414f..133f2d7 100644 --- a/packages/extractor-typescript/package.json +++ b/packages/extractor-typescript/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/extractor-typescript", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/language-server/CHANGELOG.md b/packages/language-server/CHANGELOG.md index 2e68d7c..db580e1 100644 --- a/packages/language-server/CHANGELOG.md +++ b/packages/language-server/CHANGELOG.md @@ -1,5 +1,71 @@ # @vellum-docs/language-server +## 0.3.0 + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 4d2db86..d165c5d 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/language-server", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/profile-markdown/CHANGELOG.md b/packages/profile-markdown/CHANGELOG.md index 5ec0afa..6185ed6 100644 --- a/packages/profile-markdown/CHANGELOG.md +++ b/packages/profile-markdown/CHANGELOG.md @@ -1,5 +1,71 @@ # @vellum-docs/profile-markdown +## 0.3.0 + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/profile-markdown/package.json b/packages/profile-markdown/package.json index 9f267cf..7a66b59 100644 --- a/packages/profile-markdown/package.json +++ b/packages/profile-markdown/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/profile-markdown", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git", diff --git a/packages/profile-mintlify/CHANGELOG.md b/packages/profile-mintlify/CHANGELOG.md index a75f7e0..0162faf 100644 --- a/packages/profile-mintlify/CHANGELOG.md +++ b/packages/profile-mintlify/CHANGELOG.md @@ -1,5 +1,71 @@ # @vellum-docs/profile-mintlify +## 0.3.0 + +### Patch Changes + +- ad1aa14: Add `cell` filter + `TypeString.oneline` for cell-safe rendering + + Every adopter was hand-rolling the same 5-filter escape chain when dropping types or summaries into markdown table cells: + + ```njk + {{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }} + ``` + + Two additions collapse that: + + **`TypeString.oneline?: string`** - populated at extraction time with the whitespace-collapsed form of `text`. Omitted when equal to `text` (single-line case). Fixes the `\n` + indentation problem at source, before any template filter runs. + + **`cell` filter** (profile-routed) - accepts a `TypeString`, plain string, or null. Collapses whitespace as defence-in-depth, routes through the profile's new `cell(value, ctx)` method, which wraps in a code span and escapes `|`. Works for anything cell-bound, not just types. + + Before: + + ```njk + | `{{ m.name }}` | `{{ m.type.text | replace("\n"," ") | replace(" ","") | replace("|","\\|") | replace("<","<") | replace(">",">") }}` | {{ m.doc.summary }} | + ``` + + After: + + ```njk + | `{{ m.name }}` | {{ m.type | cell | safe }} | {{ m.doc.summary | cell | safe }} | + ``` + + ### Schema additions (additive) + + - `TypeString.oneline?: string` + - `RendererProfile.cell(value: string, ctx: RenderContext): string` + + Existing extractors keep working - when `oneline` is absent the filter falls back to `.text`. Existing profiles get the new method implemented in `MarkdownProfile` and `MintlifyProfile`; third-party profiles must add a `cell` implementation. + + ### Out of scope + + `jsx-prop` and `fenced` contexts from the original request. Neither has recurring template pain today; defer until they do. + +- 6503a35: Philosophy audit fixes - strict-by-default, dead schema cleanup + + An audit against the newly-written PHILOSOPHY.md surfaced four gaps. This changeset closes them. + + **Strict template rendering is now on by default.** Principle 11 ("fail loudly at build time") was being violated by `throwOnUndefined: false` - a template with a typo (`{{ fn.doc.summaryy }}` instead of `fn.doc.summary`) silently rendered as empty string, and the docs shipped with a blank section. The `NunjucksEngine` now defaults to strict rendering: any output of an undefined value throws, which bubbles to a non-zero build exit. + + Opt-out paths, for the rare cases where silent fallback is wanted during migration: + + - Config: `new NunjucksEngine({ strict: false })`. + - CLI: `vellum build --no-strict`. + + **This is a behavior change.** Templates that relied on silent-empty for undefined values will now fail. Typical patterns that are still safe: `{% if sym.members %}`, `{{ sym.doc.summary }}` (empty string is defined), `{% for m in sym.members or [] %}`. The patterns that will now break are the ones you wanted to know about anyway. + + **Schema cleanup.** Three dead schema fields removed - they were defined but never populated by any extractor, violating principle 7 ("80% case defines the schema"): + + - `Symbol.signatureResolved?: string` - removed. + - `Member.kind` values `'index'` and `'call'` - removed from the union. Can be added back with implementation when a TS call/index-signature extractor lands or a language that needs them ships. + + **Docs drift fixes.** ARCHITECTURE.md referenced a `{{ str | tsdoc }}` filter that never existed; replaced with `{{ sym | summary }}` (which does). Principle 2 in PHILOSOPHY.md now explicitly distinguishes "pattern-aware" (OK) from "language-idiosyncratic" (not OK), so `Symbol.discriminator?` is consistent with the stated rule. + +- Updated dependencies [2a9986c] +- Updated dependencies [ad1aa14] +- Updated dependencies [6503a35] + - @vellum-docs/core@0.3.0 + ## 0.2.4 ### Patch Changes diff --git a/packages/profile-mintlify/package.json b/packages/profile-mintlify/package.json index 610b1e5..56b922f 100644 --- a/packages/profile-mintlify/package.json +++ b/packages/profile-mintlify/package.json @@ -1,7 +1,7 @@ { "name": "@vellum-docs/profile-mintlify", "type": "module", - "version": "0.2.4", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/photon-hq/vellum.git",