fix: fail the build on unresolvable partial references - #26
Merged
Conversation
A {{> name}} tag naming a partial that does not exist rendered as an empty
string, so a typo or a renamed partial silently deleted a section from every
skill that included it. Unrelated {{...}} text in the same file was rendered
away as well, and a tag in a file type substitution skips (.yaml, .py) shipped
through into output verbatim.
- unknown, malformed, and nested-unknown references now fail the build, naming
the emitted file, the nearest match, and the available partials
- only partial tags are substituted now: mustache gets a function for its
partials argument, and every other {{ is swapped for a sentinel before it
parses, so other brace text survives byte for byte, including text mustache
cannot parse as a template at all
- \{{> name}} emits a literal tag, for files that document partial syntax
- build fails, and validate reports, when a tag survives in a file type
substitution does not run on
BREAKING CHANGE: an unresolvable partial reference is now a build error rather
than rendering as an empty string.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A run of // lines above a top-level function, type, or const was doing the job of a doc comment without being one: not picked up by editors, TSDoc, or generated docs. Converted all 11 remaining sites in src/ to JSDoc, including the one added earlier on this branch. Inline // comments inside function bodies are left alone — they annotate statements, which JSDoc does not cover. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Partials could leave a skill file broken in three different ways. This closes all three.
The gap
The fix
Strict resolution. mustache accepts a function for its partials argument, so its own parser decides what is genuinely a partial tag; an unknown name throws and is rethrown naming the emitted file, the nearest match, and the available partials. Malformed references and unknown references inside a partial body fail too. With no partials configured, the error names the config key.
Partial-only substitution. Every {{ that is not a partial tag is swapped for a private-use sentinel before mustache parses, and restored afterwards. mustache still owns the semantics that are genuinely subtle (standalone-line handling and partial indentation), so partial output is byte-identical to before; everything else is preserved verbatim, including input that previously made mustache.parse throw. {{> name}} escapes a literal tag. A file that never mentions {{> is now returned byte-identical without touching mustache at all.
Build and validate guards. build fails on any tag left in emitted output in a file type substitution skips. validate runs the same scan from disk in validateFromDefinition, so it covers all five targets: error for skipped file types, warning for md-family files, which can only carry a tag via the documented escape.
Migration
Anyone relying on a missing partial rendering as nothing will now get a build error. That is the point: shipping a gutted skill file is worse than a red build. Needs the breaking label so the release notes carry it.
Testing
npm run check is green: format, lint, typecheck, 123 tests, build, docs. Two tests inverted to assert the new behaviour, eight added covering unknown / unconfigured / nested-unknown / malformed references, verbatim brace passthrough, the escape, the build guard, and the validate guard. Each partial-rendering case was diffed against the old renderer to confirm byte-identical output.
🤖 Generated with Claude Code