Skip to content

Commit e018ac3

Browse files
teallarsonclaudecursoragent
authored
fix: give hand-authored toolkit prose a source home in curation/ (#1112)
* fix: give hand-authored toolkit prose a source home in curation/ 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> * fix: satisfy the strict generator typecheck in the curation extractor 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> * fix: let the curation extractor run from any working directory 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> * fix: regenerate toolkits when curation changes * fix: let curation clear prose and show up in check-changes 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> * fix: satisfy strict types in custom-sections-diff test Use valid MergedToolkit metadata and documentation chunk types so the generator typecheck passes under the widened tsconfig from main. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: preserve curation provenance * refactor toolkit curation to MDX * narrow MDX curation refactor scope * fix: load default curation during generation * fix: preserve curated toolkit imports * fix: fail generation on unknown curated tool targets Validate curated `tool:` targets before the recoverable merge path so a mistyped target fails the run instead of landing in preserve-last-known-good recovery, where the toolkit would keep stale data and drop the chunk while CI stayed green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 76debba commit e018ac3

155 files changed

Lines changed: 3649 additions & 359 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/generate-toolkit-docs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ jobs:
7070
--llm-concurrency 15 \
7171
--exclude-file ./remove-toolkits.txt \
7272
--ignore-file ./skip-toolkits.txt \
73+
--custom-sections ./curation \
7374
--output data/toolkits
7475
working-directory: toolkit-docs-generator
7576
env:

biome.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
"!node_modules",
134134
"!public",
135135
"!toolkit-docs-generator/data/toolkits",
136+
"!toolkit-docs-generator/curation",
136137
"!scripts",
137138
"!agents",
138139
"!.vscode",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"swagger-ui-react": "5.32.6",
6666
"tailwindcss-animate": "1.0.7",
6767
"unist-util-visit": "5.1.0",
68+
"yaml": "2.8.3",
6869
"zod": "4.3.6"
6970
},
7071
"devDependencies": {

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

toolkit-docs-generator/ARCHITECTURE.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The generator does **not** render HTML. It produces structured JSON and optional
1212

1313
1. Fetch tool definitions from the Engine API or Arcade API.
1414
2. Load toolkit metadata from the design system or mock metadata.
15-
3. Load custom sections from JSON files (optional).
15+
3. Compile hand-authored Markdown and MDX curation (optional).
1616
4. Merge all data into `MergedToolkit` objects.
1717
5. Write a JSON file per toolkit and an `index.json` file.
1818
6. Optionally verify output and compute diffs.
@@ -24,7 +24,10 @@ The generator does **not** render HTML. It produces structured JSON and optional
2424
- `EngineApiSource` fetches tool metadata from the Engine API.
2525
- `ArcadeApiSource` fetches tool metadata from the Arcade API.
2626
- `DesignSystemMetadataSource` loads toolkit metadata from `@arcadeai/design-system`.
27-
- `CustomSectionsFileSource` loads custom documentation chunks from a JSON file.
27+
- `MarkdownCurationSource` compiles documentation chunks, import declarations,
28+
and subpages from the configured curation directory. When configured, that
29+
directory is globally authoritative: a missing toolkit directory means the
30+
toolkit has no authored curation.
2831
- `CombinedToolkitDataSource` merges tools and metadata into one interface.
2932

3033
### Merger
@@ -90,6 +93,7 @@ public, read-only values configured through these Vercel environment variables:
9093
## Key files
9194

9295
- `src/sources/engine-api.ts` — tool metadata from Engine API
96+
- `src/sources/markdown-curation.ts` — Markdown and MDX curation compiler
9397
- `src/sources/toolkit-data-source.ts` — unified data source
9498
- `src/merger/data-merger.ts` — merge pipeline
9599
- `src/generator/json-generator.ts` — output writer

toolkit-docs-generator/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,26 @@ deletes it and rebuilds `index.json`.
232232
- `--api-source` select `tool-metadata` (default with Engine creds), `list-tools`
233233
(only with the explicit flag), or `mock`
234234
- `--previous-output` compare against a previous output directory
235-
- `--custom-sections` load curated docs sections
235+
- `--custom-sections` load an authoritative Markdown/MDX curation directory
236236
- `--skip-examples`, `--skip-summary` disable LLM steps
237237
- `--skip-secret-coherence` disable the stale-reference scan + coverage fill (see the Secret coherence section)
238238
- `--llm-editor-provider`, `--llm-editor-model`, `--llm-editor-api-key` configure the secret-coherence editor (Sonnet 4.6 by default)
239239
- `--no-verify-output` skip output verification
240240

241+
## Authored curation
242+
243+
Store authored content below `curation/<toolkit>/`. Put injectable sections in
244+
`chunks/*.mdx`, import declarations in `imports/*.mdx`, and rich subpages in
245+
`pages/**/*.mdx`. Each file begins with YAML frontmatter for structured placement
246+
metadata; its body is the Markdown or MDX that readers see. Import files use
247+
`type: import` and contain one ESM import declaration.
248+
249+
When `--custom-sections` is set, the directory is authoritative for every
250+
toolkit. Removing the final curation file for a toolkit clears that toolkit's
251+
authored prose on the next generation run. Invalid frontmatter, invalid MDX,
252+
unknown tool targets, symlinks, unsafe subpage paths, and leftover JSON curation
253+
fail generation instead of silently falling back to stale generated content.
254+
241255
## Troubleshooting
242256

243257
- **Nothing regenerated**: `--skip-unchanged` exits early when tool definitions did not change.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
type: import
3+
---
4+
import StarterToolInfo from "@/app/_components/starter-tool-info";
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
type: section
3+
location: custom_section
4+
position: after
5+
header: "## Secrets"
6+
---
7+
## Secrets
8+
9+
This MCP Server requires the `ARCADE_API_KEY` secret to be configured. Learn how to [configure secrets](/guides/create-tools/tool-basics/create-tool-secrets).
10+
11+
### Getting your Arcade API Key
12+
13+
To use the Arcade Engine API MCP Server, you need an Arcade API key. This key authenticates your requests to the Arcade Engine.
14+
15+
Learn how to create and manage your Arcade API keys in the [API Keys documentation](/get-started/setup/api-keys).
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
type: import
3+
---
4+
import StarterToolInfo from "@/app/_components/starter-tool-info";
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
type: markdown
3+
location: auth
4+
position: after
5+
---
6+
The Arcade Asana MCP Server uses the [Asana auth provider](/references/auth-providers/asana) to connect to users' Asana accounts.

0 commit comments

Comments
 (0)