Skip to content

fix: give hand-authored toolkit prose a source home in curation/ - #1112

Open
teallarson wants to merge 6 commits into
mainfrom
chore/extract-prose
Open

fix: give hand-authored toolkit prose a source home in curation/#1112
teallarson wants to merge 6 commits into
mainfrom
chore/extract-prose

Conversation

@teallarson

@teallarson teallarson commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

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 delete documentationChunks, customImports, and subPages.

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

API + metadata ─┐
                ├─> generator + merger ─> data/toolkits/*.json ─> docs app
curation/ ──────┘             │
                              └─ force-regenerate remains lossless

The curation layer supplies the fields that do not come from an upstream API or LLM. It is loaded through the existing --custom-sections path and takes precedence over carry-forward from previous output.

Changes

  • Added 75 per-toolkit curation files, extracted verbatim from the committed artifacts.
  • Updated the custom-sections source to load a directory while retaining single-file compatibility.
  • Updated the nightly workflow to pass --custom-sections ./curation.
  • Added a re-runnable extraction script and regression coverage for forced regeneration.

Verification

  • All 117 toolkits reproduce their committed prose byte-for-byte.
  • Spot-checked rendered output across GitHub, Google Flights, Google News, ClickUp, and Jira.
  • Generator tests, typecheck, and lint pass.

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 generated data/toolkits/*.json, which could drop editorial prose on --force-regenerate or 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. Nightly generate-toolkit-docs now passes --custom-sections ./curation. Biome ignores the new directory like generated toolkits.

The custom-sections loader accepts either that directory (one <toolkitId>.json per 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. An extract-curation.ts script 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.

@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 10, 2026 9:24pm

Request Review

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>
@teallarson
teallarson force-pushed the chore/extract-prose branch from e2a5fac to 0587043 Compare August 5, 2026 20:50
@teallarson
teallarson changed the base branch from chore/single-source-of-truth to main August 5, 2026 20:50
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>
teallarson and others added 2 commits August 6, 2026 14:49
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>
@teallarson
teallarson marked this pull request as ready for review August 6, 2026 21:17
Comment thread .github/workflows/generate-toolkit-docs.yml
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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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)
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 82c289e. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant