fix: give hand-authored toolkit prose a source home in curation/ - #1112
fix: give hand-authored toolkit prose a source home in curation/#1112teallarson wants to merge 6 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
documentationChunks, customImports, and subPages have no upstream source — they lived only inside the generated data/toolkits/*.json and survived by carry-forward from the previous artifact. --force-regenerate and --overwrite-output set the previous-output directory to undefined, silently deleting all hand-authored prose (82 chunks and 2 subpages across 75 toolkits). Extract that prose into per-toolkit curation/<toolkitId>.json files and read them back through --custom-sections, which the merger treats as authoritative over carry-forward. The nightly workflow now passes --custom-sections ./curation, so a forced regeneration preserves prose instead of wiping it. - custom-sections-file source now loads a directory of per-toolkit files (single-file layout still supported) - scripts/extract-curation.ts is the one-time, re-runnable extractor - curation/ is excluded from biome like its sibling data/toolkits/ - regression test asserts prose survives --force-regenerate Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e2a5fac to
0587043
Compare
scripts/ is not type-checked today; #1106 widens the generator project to cover it, and under exactOptionalPropertyTypes plus noUncheckedIndexedAccess this PR's files do not compile. Fixing it here keeps the PR green whichever order the two land in. - isNonEmptyArray returned boolean, so it narrowed nothing and the caller compensated with an 'as DocumentationChunk[]' cast. Making it a type predicate narrows properly and lets the cast go. - previousToolkit is declared optional but --force-regenerate and --overwrite-output pass it explicitly as undefined, which exactOptionalPropertyTypes rejects. The type now says '| undefined', matching what callers actually do — that explicit undefined is the exact scenario the prose regression test covers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sibling generator scripts (validate-merge, sync-toolkit-sidebar, check-stale-summaries, report-tool-metadata) resolve data/toolkits through the shared resolver, which anchors on the repo root. This script used bare relative paths, so it only worked when invoked from toolkit-docs-generator/ and failed from the root — two conventions for the same directory. Anchor on the script's own location instead, matching how verify-toolkit-join, sync-toolkit-sidebar, and validate-merge already use import.meta.url. It now works from either directory. Verified from both: identical output, 75 files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a curation file exists, treat its contents as authoritative so an
empty {} file deletes hand-authored prose instead of carrying it forward.
check-changes now diffs curation against committed artifacts too.
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 82c289e. Configure here.
| }; | ||
| return ( | ||
| stableStringify(currentSections) !== stableStringify(previousSections) | ||
| ); |
There was a problem hiding this comment.
Curation diff mismatches merge semantics
High Severity
getChangedToolkitIdsFromCustomSections unions every previous toolkit id and treats a missing curation entry as empty sections. Merge treats a missing file as null and carry-forwards. Any drift between curation/ and artifact prose—including secret-coherence edits to documentationChunks—marks the toolkit changed forever under --skip-unchanged, so nightly generation can regenerate those toolkits on every run.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 82c289e. Configure here.


Why
Hand-authored toolkit prose was stored only in generated
data/toolkits/*.json. A forced regeneration has no previous output to carry forward, so it could silently deletedocumentationChunks,customImports, andsubPages.This gives that content a durable source of truth in
curation/, so nightly generation can rebuild the JSON without losing editorial work.How it fits
The curation layer supplies the fields that do not come from an upstream API or LLM. It is loaded through the existing
--custom-sectionspath and takes precedence over carry-forward from previous output.Changes
--custom-sections ./curation.Verification
Independent of #1106 and #1113; #1111 documents the hazard this fixes.
Note
Medium Risk
Changes docs generation merge semantics and CI inputs; incorrect curation or authoritative clearing could alter published toolkit pages, though behavior is covered by new tests and is largely a content relocation.
Overview
Hand-authored toolkit content (
documentationChunks,customImports,subPages) no longer depends on carry-forward from generateddata/toolkits/*.json, which could drop editorial prose on--force-regenerateor a clean output dir.This PR adds
toolkit-docs-generator/curation/(75 per-toolkit JSON files, migrated from existing artifacts) as the durable source of truth. Nightlygenerate-toolkit-docsnow passes--custom-sections ./curation. Biome ignores the new directory like generated toolkits.The custom-sections loader accepts either that directory (one
<toolkitId>.jsonper toolkit) or the legacy single JSON map. When curation is loaded for a toolkit, the merger treats it as authoritative: an empty{}clears prior prose instead of preserving it from the last artifact.check-changes/ incremental generate compare curation to the previous output and flag curation-only toolkit IDs for regen. Anextract-curation.tsscript supports one-time extraction; tests cover directory loading, curation diff, authoritative clear, and prose surviving force-regenerate.Reviewed by Cursor Bugbot for commit 82c289e. Bugbot is set up for automated code reviews on this repo. Configure here.