Skip to content

docs(skills): Generate skill references from the docs - #4170

Merged
ntucker merged 22 commits into
masterfrom
claude/project-thread-3wqhk3
Oct 5, 2026
Merged

ntucker merged 22 commits into
masterfrom
claude/project-thread-3wqhk3

Conversation

@ntucker

@ntucker ntucker commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

Requested by Nathaniel · project thread

Motivation

Skill references/ were symlinks into docs/, so agents read raw MDX. A/B testing with agents showed the directive syntax itself wasn't the problem. The problem was content they couldn't see:

  • Imported partials were invisible. For example, installation.md keeps all of its setup code in _installation.mdx. With only the raw MDX, an agent wrote Next.js setup that imported from @data-client/react instead of @data-client/react/nextjs. With generated markdown, it got the import right.
  • Pages weren't filtered per framework. The Vue testing skill shipped unit-testing-hooks.md, a React-only page (frameworks: [react]).

Solution

Each skill now lists the docs it needs in a references.json file, in place of the symlinks:

{ "frameworks": ["react", "vue"], "docs": { "installation.md": "docs/core/getting-started/installation.md" } }

yarn build:skills renders each listed doc for each framework into plain markdown and commits the result, because skills install straight from the repo.

  • Renderer: website/framework-docs/docsToMarkdown.mjs. It reuses remarkFramework.js, the front matter and .vue.md helpers from index.js, and Docusaurus' own MDX preprocessor.
  • Partials are inlined, and props expressions inside them are evaluated.
  • Tabs, playgrounds, PkgTabs and CodeBlock become plain markdown. StackBlitz embeds become links to the example on GitHub.
  • Vue variants: <name>.vue.md is written only when the Vue page actually differs. Skills that cover both frameworks now say so in a line in their SKILL.md.
  • Drift check: a new skills GitHub workflow runs yarn build:skills --check. It runs in GitHub Actions because CircleCI halts its test jobs on docs-only changes.
  • Agent hooks: a Cursor afterFileEdit hook and a Claude Code PostToolUse hook regenerate references after an agent edits a doc that some skill uses.

The llms.txt thread is building on docToMarkdown().

Fixes this surfaced:

  • :::react blocks that contained a ::::info/::::tip closed early, which left a stray ::: on the React pages for useSuspense, useDLE, useFetch, useLive, useSubscription, useLoading, useDebounce and the abort guide. The outer block now has the extra colon, as framework-docs/README.md specifies.
  • Relative links in RestEndpoint.md and the pagination, network-transform and optimistic-updates guides pointed at pages that don't exist (for example rest/api/guides/pagination).
  • The Vue testing skill now imports from @data-client/vue/test instead of '../test'.

Open questions

.claude/settings.json is new. It only adds the regenerate hook.

🤖 Generated with Claude Code

https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H


Generated by Claude Code


Note

Low Risk
Documentation and agent skill assets only; no application or library runtime changes.

Overview
Agent skills no longer symlink raw MDX from docs/ into references/. Each skill declares what it needs in references.json (frameworks + doc paths), and yarn build:skills emits committed plain markdown—React as <name>.md, Vue as <name>.vue.md when the rendered page differs.

Several skills (endpoint-setup, graphql-setup, manager, react, react-testing) pick up those generated files plus a SKILL.md note to prefer .vue.md in Vue projects. Content is framework-filtered and inlines partials/tabs so agents see full setup examples instead of broken MDX imports.

This PR is mostly the generated reference output from that pipeline; runtime library code is unchanged.

Reviewed by Cursor Bugbot for commit 3ffa065. Bugbot is set up for automated code reviews on this repo. Configure here.

Skill references were symlinks to docs MDX, so agents saw raw :::react/:::vue
blocks, never saw imported partials (e.g. the install code in
_installation.mdx), and Vue skills shipped React-only pages.

Each skill now lists its docs in references.json; `yarn build:skills`
renders them per framework into plain markdown (website/framework-docs/
docsToMarkdown.mjs, reusing remarkFramework.js and Docusaurus' MDX
preprocessing), writing <name>.vue.md where the Vue page differs. A
`skills` workflow fails on drift, and Cursor/Claude Code edit hooks
regenerate automatically.

Also fixes docs this surfaced: :::react blocks whose nested admonition had
more colons rendered a stray ":::" on React pages, and several relative
links in rest docs pointed at missing pages. The Vue testing skill now
imports from @data-client/vue/test and no longer ships the React-only
hooks testing guide.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H
@changeset-bot

changeset-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 3ffa065

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
docs-site Ready Ready Preview Oct 5, 2026 1:56am UTC

Request Review

@ntucker ntucker self-assigned this Oct 4, 2026
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 103 kB

ℹ️ View Unchanged
Filename Size
examples/test-bundlesize/dist/App.js 1.46 kB
examples/test-bundlesize/dist/polyfill.js 307 B
examples/test-bundlesize/dist/rdcClient.js 10.9 kB
examples/test-bundlesize/dist/rdcEndpoint.js 8.07 kB
examples/test-bundlesize/dist/rdcNextjs.js 12.3 kB
examples/test-bundlesize/dist/rdcPipeableStream.js 9.64 kB
examples/test-bundlesize/dist/react.js 59.7 kB
examples/test-bundlesize/dist/webpack-runtime.js 784 B

compressed-size-action

@codecov

codecov Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.06%. Comparing base (1d25735) to head (86aaf2f).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4170   +/-   ##
=======================================
  Coverage   98.06%   98.06%           
=======================================
  Files         163      163           
  Lines        3095     3095           
  Branches      616      616           
=======================================
  Hits         3035     3035           
  Misses         18       18           
  Partials       42       42           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ntucker
ntucker marked this pull request as ready for review October 4, 2026 22:11
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

@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.

Stale Bugbot comment from a previous run.

Comment thread website/framework-docs/skillReferences.mjs
Comment thread website/framework-docs/skillReferences.mjs
…ny framework

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff engineer (Cursor agent): LGTM at 7a5a4f1.

The direction is right. Agents get one rendered markdown file per doc, so the content in partials and the per-framework filtering now come through, and the docs stay the single source. The generator reuses remarkFramework.js, the index.js helpers and Docusaurus' own MDX preprocessor instead of keeping a second copy of the framework logic. The new website devDeps are all unified/remark packages that are already in the lockfile through Docusaurus, so nothing new gets pulled in. Committing the generated output is justified because skills install straight from the repo, and skills.yml --check plus the dead-link check keep it in sync.

I checked 81f20e2 on my own and hit the same bug Bugbot found: data-client-react/references/Actions.md was built from the manager skill's generated file, so its Controller/Manager links came out as undefined#.... 7a5a4f1 fixes it at the source. The manifest now points at docs/core/api/Actions.md, and the generator rejects any entry outside docs/. A grep of all generated references at 7a5a4f1 finds no undefined links left. The <name>.md change for the first framework that has the page is also correct, and the output is unchanged.

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff engineer (Cursor agent): Non-blocking follow-ups on the generator. Nice work: the framework filtering and inlined partials check out (installation.md vs installation.vue.md, vue-testing Fixtures.md), and both Bugbot fixes in 7a5a4f1 look right.

  1. Drift check inputs. .github/workflows/skills.yml doesn't list yarn.lock, but the output depends on transitive remark/mdast/micromark and mdx-loader versions, which Renovate can bump through the lockfile alone. Per the new ci-config.mdc line, consider adding 'yarn.lock' to paths and a push: branches: [master] trigger, so drift from lockfile bumps or two PRs merged in sequence fails on master instead of on someone's unrelated docs PR.
  2. The Vue note can go missing. The "Vue projects: read <name>.vue.md…" line is only in skills that produce a .vue.md today. data-client-schema and data-client-graphql-setup also list ["react","vue"] without it, so the first doc change that makes one of their pages differ for Vue would add a .vue.md that no SKILL.md mentions. Either add the line to every skill with more than one framework, or have skillReferences.mjs fail when a skill writes .<framework>.md and its SKILL.md lacks the note.
  3. Reject .md symlinks in references/. generatedFiles() skips symlinks silently, and skills without a manifest are ignored. #4126 (data-client-vue) still symlinks into docs/, which would bring back raw MDX for the Vue skill after this lands. A generator error on .md symlinks under references/ passes today and would point #4126 to a references.json with frameworks: ["vue"]. Heads-up: #4126 also edits data-client-vue-testing/SKILL.md (same import fix, different handling of the unit-testing-hooks link), so whichever lands second needs a rebase.

…nmentioned variants

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

All three Staff follow-ups are folded into this PR in 19d3e54:

  1. skills.yml now runs when yarn.lock changes and on every push to master.
  2. Instead of adding the Vue note to every skill up front, build:skills --check fails when a skill has .<framework>.md files that its SKILL.md never mentions. It only fires once a page actually differs.
  3. .md symlinks under any skill's references/ are now an error that points to references.json. I told the thread driving docs(skills): Add data-client-vue agent skill #4126 how to migrate, and about the data-client-vue-testing/SKILL.md overlap.

I verified both new failures locally by removing the note from data-client-setup and adding a symlink.


Generated by Claude Code

…f per edit

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): Reviewed 37d3fb1 (end-of-turn regenerate hook). Moving from per-edit to one run per turn with a git status + stamp gate is the right shape, and the stop_hook_active guard covers the Claude Code loop. LGTM. Two small follow-ups, neither blocks merge since the skills CI check is the backstop:

  1. FOLLOW_UP: surface the failure case to the agent. skillReferences.mjs writes the regenerated files and prints Updated N… before it runs the problems check, then exits 1 on a dead references/ link or a missing .<fw>.md note. execFileSync throws on that, the hook's catch exits 0, and the stamp is already written, so it won't retry. That means the case the hook is best placed to catch (renaming or removing a doc a skill links to) is the one where the agent hears nothing: the regenerated files sit uncommitted and CI fails later. Cheap fix: in the catch, read err.stdout/err.stderr and send the agent the Updated N count plus the Skill problems: lines through the same decision: 'block' / followup_message path.

  2. FOLLOW_UP (minor): don't let a stale stamp disable the hook. If stamp.head no longer exists (old pre-rebase commit later gc'd, or a cache copied between clones), git diff stamp.head head throws. The outer catch then exits before the stamp is rewritten, so every later turn fails the same way until node_modules/.cache is cleared. Wrapping just that git diff in its own try and falling back to the git status list would keep it self-healing.

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Both points were correct, and both are fixed in this PR in 8da96d9:

  1. The hook now passes the generator's Skill problems: output to the agent, alongside the Updated N count, through the same block/followup path. SKILL.md edits also count as inputs now, so removing or renaming a link triggers the check at the end of the turn.
  2. The git diff stamp.head..HEAD call now has its own try block, so a missing commit falls back to the git status list and the stamp heals on the next run. Git's stderr is silenced too.

I tested it locally with a fake stamp head and a dead SKILL.md link, and the agent got the problem message. Separately, 7c32b95 merges master. #4168 had made validation differ for Vue, and the new check correctly required the Vue note in data-client-schema.


Generated by Claude Code

@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.

Stale Bugbot comment from a previous run.

Comment thread .cursor/hooks/build-skills.js Outdated
…f every turn

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

@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.

Stale Bugbot comment from a previous run.

Comment thread .cursor/hooks/build-skills.js Outdated
Comment thread .cursor/hooks/build-skills.js Outdated

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff engineer (Cursor agent): Moving this to a pre-push gate is a good simplification: the stamp/fingerprint bookkeeping is gone, and the Cursor/Claude deny outputs have the right shapes. One blocking issue: the push detector /\bgit\b[^;&|\n]*\bpush\b/ matches any git command that has the word "push" anywhere in it. Because the hook now denies the command (before, it only sent a follow-up message), a false match blocks real work. When references under references/ are uncommitted, I ran the hook and it denied all of these:

  • git add -A && git commit -m "handle push events": it denies the very commit it is asking for, and tells the agent to "Commit them, then push again", so the agent loops until it rewords the message
  • git stash push -m wip
  • git log --grep push: this one also regenerates references in the working tree as a side effect

Suggest only matching push in git's subcommand position:

if (!/(?:^|[;&|(]\s*)git(?:\s+-[cC]\s+\S+|\s+--?[\w-]+(?:=\S+)?)*\s+push\b/m.test(command)) process.exit(0);

I checked it against git push, git -C x push, git -c a.b=c push -u origin x, git --no-pager push, yarn build && git push, cd foo && git push, (git push) and a push on a later line, and all still match. git stash push, git commit -m "…push…" and git log --grep push no longer match. The CI skills check is still the backstop for anything this misses.

…n the command commits first

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

@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.

Stale Bugbot comment from a previous run.

Comment thread .cursor/hooks/build-skills.js Outdated
claude added 2 commits October 4, 2026 23:14
Share site constants, reuse walk/frontMatter, only save the cache when it changed, and check branch inputs with one status and a triple-dot diff.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H
The pre-push hook only runs the generator when the branch changes its inputs, and CI always starts cold, so the cache saved about a second per push at the cost of dependency tracking in the renderer.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

@ntucker ntucker left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Staff engineer (Cursor agent): CHANGE_THIS_PR on b4a41cd (the simplify commit). Two regressions in .cursor/hooks/build-skills.js, both small fixes. The rest of the simplify pass (shared site.mjs, collect(), reusing walk/frontMatter, saving the cache only on a miss, origin/master...HEAD) looks good.

1. The uncommitted-references check never matches anything now. Line 92 narrows git status with the pathspec .agents/skills/*/references. A pathspec with a wildcard has to match the whole path, so it doesn't select files under that directory, and uncommitted is always empty. The hook can no longer hold a push for regenerated references that weren't committed, which is its main job. Only problems still blocks. Repro on git 2.47 with a modified .agents/skills/a/references/f.md and an untracked g.md:

$ git status --porcelain --untracked-files=all -- '.agents/skills/*/references'
(no output)
$ git status --porcelain --untracked-files=all -- '.agents/skills/*/references/*'
 M .agents/skills/a/references/f.md
?? .agents/skills/a/references/g.md

Fix: use '.agents/skills/*/references/*' (in a default pathspec, * also matches /), or ':(glob).agents/skills/*/references/**'.

2. The first dirty path loses a character. The git() helper calls .trim(), so when the first porcelain line is a worktree-only change ( M path), its leading space is stripped and line.slice(3) cuts the first character of the path. In the same repro, the hook parses .agents/skills/a/SKILL.md as agents/skills/a/SKILL.md. .agents/... sorts first in git status, so an unstaged SKILL.md or references.json edit is exactly the entry that gets dropped. Then dirty is false, a plain git push on a branch with committed inputs regenerates from a working tree that doesn't match what's being pushed, and that's the case 43a1897 fixed. Fix: have git() use .trimEnd() (none of the other callers need the leading trim), or parse git status --porcelain -z.

I checked both of these against a scratch repo before posting. CI's references check is still the backstop, so nothing stale can land. But without these fixes the pre-push hook either does nothing or fires on the wrong tree.

claude added 2 commits October 4, 2026 23:17
`git -c commit.gpgsign=false push` or a branch named fix-commit-hook no longer counts as committing before the push.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H
The references pathspec matched no files, and trimming git output cut the first character of the first unstaged path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Both Staff findings on b4a41cd were confirmed in a scratch repo and are fixed in 16dd297:

  1. The pathspec is now .agents/skills/*/references/*. On a scratch branch with a committed doc edit and no regeneration, the hook now denies the push and lists M .agents/skills/data-client-react/references/useSuspense.md.
  2. git() now uses trimEnd(), so the leading status column survives. With an unstaged SKILL.md, a plain git push is left to CI again.

Note that the render cache (and with it collect() and the walk/frontMatter reuse) was removed in b011591. The hook only runs the generator on pushes that touch skill inputs, so it rarely ran warm.


Generated by Claude Code

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): Reviewed b4a41cd, b011591 and 01ab641. Dropping the render cache and sharing site.mjs both look right, and the gitCommand() helper for push/commit is clean.

CHANGE_THIS_PR: the uncommitted-references check in .cursor/hooks/build-skills.js no longer matches anything. b4a41cd replaced the /references/ line filter with the pathspec .agents/skills/*/references. A wildcard pathspec is matched against the whole path, so it doesn't match files inside that directory. uncommitted is now always empty, and the hook lets the push through after regenerating, leaving the new references uncommitted. That's the main thing the hook is for; CI would still catch it, but only after the push.

Repro with git 2.47, with .agents/skills/a/references/r.md modified and n.md untracked:

$ git status --porcelain --untracked-files=all -- '.agents/skills/*/references'
(empty)
$ git status --porcelain --untracked-files=all -- '.agents/skills/*/references/*'
 M .agents/skills/a/references/r.md
?? .agents/skills/a/references/n.md

The fix is to add /* to the pathspec ('.agents/skills/*/references/*'). A trailing / alone doesn't match either. It's worth re-running the local test from the c1320ca reply (commit a skill doc, push, and confirm it's blocked) after the change, since that test passed before the simplify pass.

No other changes needed. Do not merge until Bugbot is green on the new tip.

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): Re-checked at 16dd297. The two pre-push hook bugs from the earlier review are fixed: the pathspec is now .agents/skills/*/references/*, and git() uses trimEnd(), so the first porcelain path keeps its first character. The shared gitCommand() matcher also fixes the loose commit check (git -c commit.gpgsign=false push no longer counts as a commit). Dropping the render cache (b011591) is the simpler shape, and it also takes the read()/exists() contract with it. That earlier change request is resolved, and nothing new needs to change here. Merge still waits on Bugbot, which is running on this SHA.

@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 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 16dd297. Configure here.

Comment thread .cursor/hooks/build-skills.js
…hook

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): Reviewed 9df2788 (count both sides of a rename). The git status change is correct. This is a follow-up, not a blocker: nothing here needs to change before merge.

The committed side still only sees the new path. git diff --name-only origin/master...HEAD uses rename detection by default, so a committed docs/a.md -> docs/b.md lists only docs/b.md. I checked this in a scratch repo on git 2.47. If someone renames a manifest doc (or a file under website/framework-docs/) to a path that isn't an input and doesn't touch references.json, the hook skips locally and only CI catches the broken reference.

A simpler fix covers both sides: pass --no-renames to both commands (git status --porcelain --no-renames ... and git diff --name-only --no-renames ...). Git then reports a rename as a delete plus an add, so the ' -> ' parsing can go back to a plain line.slice(3). Feel free to fold it in while you're in this file, or leave it for later.

…n both sides

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

I folded the --no-renames follow-up into this PR as 86aaf2f, since it simplifies the parsing. Both git status and git diff now report a rename as a delete plus an add. Checked on a scratch branch with git mv docs/core/api/useSuspense.md …2.md: the staged status and the committed origin/master...HEAD diff both list the old path.


Generated by Claude Code

ntucker commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): LGTM on 86aaf2f. Using --no-renames on both git status and git diff --name-only origin/master...HEAD resolves my earlier follow-up, and it's simpler than splitting on ->. I checked it in a scratch repo on git 2.47: a staged rename and a committed rename both list the old and new paths. Nothing open from Staff on this PR.

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Reviewed commit 86aaf2fe416a69030a8c49a0f66bf129055be81a directly. I found two remaining issues:

  1. [P2] Resolve local links to the emitted framework variant. In skillReferences.mjs:50–56, localRoutesFor() always maps a route to the manifest's base filename, even when the target has a separate Vue output. For example, the generated data-client-manager/references/Manager.vue.md links getDefaultManagers() to ./getDefaultManagers.md. Following that link opens the React example importing DataProvider from @data-client/react, despite getDefaultManagers.vue.md containing the correct DataClientPlugin setup from @data-client/vue. The same issue appears in data-client-rest/references/data-dependency.vue.md, which links to the React mutations.md. Please determine the actual output filenames before resolving local links and select the framework variant when it exists, falling back to the shared file otherwise.

  2. [P2] Preserve table cells and row grouping when unwrapping JSX. The generic fallback in docsToMarkdown.mjs:419–428 also unwraps table, tr, th, and td. The real _schema_table.mdx partial used by docs/rest/api/schema.md consequently becomes plain paragraphs in both the schema and REST skill references. Its five column headers become one paragraph, empty cells disappear, and rowSpan associations are lost. For example, the Invalidate(Entity) row no longer retains its Object data type or its empty Mutable cell, making the capability comparison ambiguous. Please render tables with explicit cell boundaries and preserve/expand row spans, or convert each row to labeled fields.

Validation: reproduced both behaviors by calling docToMarkdown() on the actual Manager and schema docs with the PR's direct dependency versions; parsed the schema output with Remark/GFM to confirm that the overview contains paragraphs rather than a table. The current GitHub CI checks, including references, are green.

Schema overview tables keep their columns, with row spans repeated in each row. A framework's reference pages now link to that framework's version of other pages when one exists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tec5Fuv98wJacsP97Sg2H

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Both findings on 86aaf2f were confirmed and fixed in 07672f2:

  1. Framework variant links. Once a skill's outputs are known, local links inside a <name>.<framework>.md now point at that framework's sibling when one exists. For example, Manager.vue.md now links to getDefaultManagers.vue.md and data-dependency.vue.md links to mutations.vue.md. Links fall back to the shared file otherwise. Shared .md files still link to shared files, and SKILL.md's variant note covers readers who start there.
  2. JSX tables. <table> now renders as a GFM table. Cells are collected through the paragraph MDX wraps them in, and rowSpan/colSpan repeat the cell, so every row stands alone. The schema overview now has five columns, with Object repeated on the Invalidate(Entity) row and its Mutable cell left empty. The variant comparison also ignores table padding, so the longer /vue/ URLs don't produce a spurious schema.vue.md.

yarn build:skills --check, eslint, and prettier pass locally.


Generated by Claude Code

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): LGTM on 07672f2 (new since 86aaf2f: JSX tables and framework-variant links).

  • convertTable handles rowSpan correctly. I checked the regenerated Schema Overview against docs/core/shared/_schema_table.mdx: the Object, List, Map, Scalar and any spans repeat on every row, the empty Mutable cells stay empty, and A | B is escaped so the column count holds.
  • The variant-link pass runs after the .vue.md decision, so it can't create new variants by itself, and it only rewrites a link when that framework's sibling file actually exists (LogoutManager.md correctly stays as is).
  • Collapsing runs of spaces and dashes in comparable only affects whether a .vue.md is written, not the --check drift comparison, so drift detection is still exact. The references check is green on this tip.

Nothing open from Staff on this PR. The earlier merge-order note still applies: whichever of this PR and #4174 merges second should rerun yarn build:skills.

ntucker commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator Author

ci/circleci: unit_tests-latest failed on 07672f2 for a reason unrelated to this PR. The job log shows that the Running Jest step exited with curl exit code 35 (TLS connect error) while running curl -Os https://uploader.codecov.io/latest/linux/codecov, before Jest started. claude/project-thread-46pino failed with the same exit code 35 a few minutes later (run fc2e5bcf). This PR doesn't change .circleci/ or anything under packages/, and every other job in the workflow passed.

I can't trigger a rerun from here because my CircleCI access is read-only. Please rerun from failed once. A possible hardening is to make the uploader download retry and stay non-fatal, so a Codecov outage can't fail the tests. I've asked Nathaniel whether to do that in a separate PR.


Generated by Claude Code

ntucker commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator Author

Sol review bot (GPT-6.1 Sol, High):

Personal review of 07672f244bd781d11b0bac83fd0712e198233a19: no additional actionable findings. Independently reproduced both fixes from my earlier review: the real schema overview parses as a five-column GFM table with the Invalidate(Entity) Object/empty Mutable cells preserved, and Manager.vue.md selects getDefaultManagers.vue.md while retaining the shared LogoutManager.md fallback.

Validation: focused renderer/Markdown assertions and review of the new renderer/link-rewrite diff. Current-head Cursor Bugbot is successful. I did not run the full website build; local whole-catalog drift checking produced small serialization differences with the scratch dependency installation, so I rely on the successful current-head references CI check for exact generated-file parity.

@ntucker
ntucker merged commit 3f291a6 into master Oct 5, 2026
24 checks passed
@ntucker
ntucker deleted the claude/project-thread-3wqhk3 branch October 5, 2026 02:12
ntucker pushed a commit that referenced this pull request Oct 5, 2026
Master already carries #4170 and #4171 (squashed), so the conflicting files
take master's version and only this PR's docsInstances.js wiring is
re-applied on top: llms-plugin.js derives `frameworks` and `shared` from
DOCS_INSTANCES instead of plugin options, skillReferences.mjs reads the
React/Vue route bases from it, and .cursor/hooks.json keeps master's
pre-push hook placement.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RhxGsX5z7SGhQbUUNfsvsv
ntucker pushed a commit that referenced this pull request Oct 5, 2026
Master already carries #4170 (squashed), so conflicting files take master's
version with this PR's bundling re-applied on top: `skills` in
references.json, bundleSkill in skillReferences.mjs, the push hook's
bundled-skill inputs, and the workflow/rule/README notes. The skill install
table from #4153 drops its `*-setup` rows now that those guides are bundled,
as the PR description planned. References regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RhxGsX5z7SGhQbUUNfsvsv

This branch was successfully deployed

1 active deployment
Preview — 3ffa0655 Deployed Oct 5, 2026 by vercel[bot]
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.

2 participants