Skip to content

chore: progressive-disclosure rules restructure + fix silently-broken Vercel docs fetch#47

Merged
LukeMainwaring merged 3 commits into
mainfrom
rules-setup
May 13, 2026
Merged

chore: progressive-disclosure rules restructure + fix silently-broken Vercel docs fetch#47
LukeMainwaring merged 3 commits into
mainfrom
rules-setup

Conversation

@LukeMainwaring

Copy link
Copy Markdown
Owner

Summary

  • Fix: /updating-deps Phase 4 was a silent no-op for weeks — its AWK extraction was anchored on # AI SDK UI / # AI_APICallError section headers Vercel removed when they restructured llms.txt around guides. AWK printed nothing → > truncated the file. Replaced with a sitemap-filtered fetch of Fumadocs' documented .md raw-markdown variant, plus loud sanity assertions. Mirrors cortexdj#43.
  • Restructure: Adopt cortexdj's progressive-disclosure layout for Claude Code instructions — paths: frontmatter on every .claude/rules/**.md, router pointers in CLAUDE.md instead of inline doc paragraphs, new frontend/vercel-ai-sdk.md capturing samplespace's chat-surface conventions. CLAUDE.md drops from 11 KB → 7.6 KB without losing samplespace-specific facts.
  • Doc refresh: docs/vercel-ai-sdk-ui.txt rebuilt as a side-effect of verifying the new Phase 4 script: 99 KB → 271 KB across 28 source pages, now reflects the AI SDK 5/6 transport API the codebase is already using.

Changes

Skill fix (.claude/skills/updating-deps/SKILL.md)

  • Phase 4 AI SDK block replaced with a sitemap-driven, fail-loud script (set -eo pipefail, mktemp+trap cleanup, curl -fsSL, empty-sitemap assertion, useChat-presence assertion, >100 KB size assertion). Catches each realistic upstream-restructure failure mode distinctly.
  • Verified end-to-end on this macOS shell: 28 URLs, 271 KB output, 172 useChat mentions across 28 <!-- source: --> markers.

Rules restructure (.claude/rules/**, CLAUDE.md)

  • paths: YAML frontmatter on all four rule files — machine-readable scope globs that also document each rule's intended file scope.
  • New .claude/rules/frontend/vercel-ai-sdk.md capturing samplespace-specific chat-surface facts:
    • UI-only / no Core server-side; app/(chat)/api/chat/route.ts is a thin proxy to POST /api/agent/chat
    • useChat<ChatMessage> is on the v5/v6 DefaultChatTransport + sendMessage shape — no handleInputChange / handleSubmit / input from useChat
    • ChatMessage = UIMessage<Record<string, never>, CustomUIDataTypes> — metadata slot intentionally empty, not never
    • Renderable blocks (sample-results, kit, kit-preview, audio, pair-verdict) dispatched in message.tsx::DataPartRenderer via part.type === "data-<name>"; adding a new block is lib/types.ts + DataPartRenderer case
    • Non-rendering data parts (chat-title) go to data-stream-handler.tsx, not DataPartRenderer
    • ChatActionsProvider carries sendMessage to descendants via context
  • CLAUDE.md:
    • Hoist "all commands run from repo root" to the top of ## Common Commands
    • Trim the per-component frontend file list from ~14 to ~6 (chat, message+DataPartRenderer note, sample-browser + sample-detail-panel, elements/, api/hooks/, components/ui/) — dropped entries are still discoverable by name
    • Fix stale paths: app/page.tsxapp/(chat)/page.tsx, app/api/chat/route.tsapp/(chat)/api/chat/route.ts, drop nonexistent audio-player.tsx; backend route is /api/agent/chat not /agent/chat
    • Replace inline Pydantic AI / Vercel AI SDK paragraphs with four router pointers into .claude/rules/
    • Drop the "95% confidence — ask via AskUserQuestion" rule (behavioral guidance, not a project fact)
    • Keep samplespace-specific facts: Rubber Band on PATH, CLAP/CNN mock-in-tests, SAMPLE_LIBRARY_DIR, manual git, pnpm -C frontend build skipped for validation

Differences vs. cortexdj's verbatim layout

  • No backend/modal.md — samplespace doesn't use Modal
  • frontend/vercel-ai-sdk.md documents data-<name> part dispatch, not tool-<name> like cortexdj — samplespace agents emit data parts, not tool-typed parts
  • Kept the samplespace-only Additional Instructions items cortexdj has no analog for

Code review

Reviewed by the code-reviewer subagent. One material correctness issue caught and fixed in commit a0644a5: the original vercel-ai-sdk.md carried a "chat surface still uses pre-v5 API" heads-up that was pattern-matched from cortexdj's PR description but is false here — samplespace already uses DefaultChatTransport + sendMessage. Replaced with a positive description of the actual API surface. Also corrected ChatMessage signature drift, the missing 6th CustomUIDataTypes entry (chat-title), and three /agent/chat/api/agent/chat route references.

Test Plan

  • CI green (no backend Python or frontend code changes, but pre-commit hooks still run on the markdown)
  • Spot-check one routing pointer end-to-end: open a fresh session, edit any backend/src/samplespace/agents/**.py file, confirm Claude finds .claude/rules/backend/pydantic-ai.md quickly
  • Next /updating-deps run: confirm the new Phase 4 block actually runs and docs/vercel-ai-sdk-ui.txt regenerates with all four assertions passing
  • Skim vercel-ai-sdk.md against frontend/components/chat.tsx — every claim in the rule should match the code (this is the file the code-review pass fixed)

🤖 Generated with Claude Code

LukeMainwaring and others added 3 commits May 13, 2026 13:06
The Phase 4 block in /updating-deps was a silent no-op — its AWK
extraction was anchored on '# AI SDK UI' / '# AI_APICallError' section
headers that Vercel removed from llms.txt when they restructured the
index around guides. AWK printed nothing → '>' truncated the file.

Replaced with a sitemap-filtered fetch of Fumadocs' documented .md
raw-markdown variant (x-matched-path: /[variants]/llms.mdx/[type]/[...slug]),
plus loud assertions for empty sitemap filter, missing 'useChat', and
unexpectedly small output. Mirrors LukeMainwaring/cortexdj#43.

CLAUDE.md previously re-inlined the same broken one-liner; now points
to the skill block with a one-line note on why the old command failed,
so future-me doesn't restore it.

docs/vercel-ai-sdk-ui.txt refreshed as a side-effect of verifying the
new script end-to-end: 99 KB → 271 KB across 28 source pages, now
reflects the AI SDK 5/6 transport API (sendMessage,
DefaultChatTransport, parts-based messages) instead of the pre-v5
handleInputChange/handleSubmit/input pattern. Migrating chat.tsx to the
new surface is deferred to its own PR (Vercel ships
'pnpm dlx @ai-sdk/codemod v6' for the bulk rewrite).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the structure that landed in cortexdj — same routing pattern,
project-specific content.

CLAUDE.md (11 KB → 7.6 KB):
- Hoist 'all commands run from repo root' to the top of Common Commands
- Fix stale frontend paths: app/page.tsx → app/(chat)/page.tsx,
  app/api/chat/route.ts → app/(chat)/api/chat/route.ts; the (chat) route
  group has been in place for a while but the doc never caught up
- Trim the per-component file list from ~14 to ~6 entries (chat, message
  with DataPartRenderer note, sample-browser + sample-detail-panel,
  elements/, api/hooks/, components/ui/) — dropped files are still
  discoverable by name
- Replace inline paragraphs about Pydantic AI / Vercel AI SDK docs with
  router pointers into .claude/rules/ — each pointer is 'when to read it'
  + a one-sentence preview of what's inside
- Drop the '95% confidence — ask via AskUserQuestion' rule; it's
  behavioral guidance about how Claude works, not a samplespace fact
- Keep samplespace-specific facts not derivable from code: Rubber Band
  on PATH, CLAP/CNN mock-in-tests, SAMPLE_LIBRARY_DIR, manual git, and
  the regenerate-client reminder

.claude/rules/ — frontmatter on every file:
- All four rule files now open with paths: globs (machine-readable
  scope; also documents intent for readers)
- backend/code-conventions.md: backend/**/*.py
- backend/pydantic-ai.md: agents/**/*.py + tests/evals/**/*.py
- frontend/code-conventions.md: components/app/hooks/api-hooks/lib
- frontend/vercel-ai-sdk.md (NEW): same scope as frontend conventions
  minus app/ subset, narrowed to app/(chat)/

.claude/rules/frontend/vercel-ai-sdk.md (new) captures samplespace-specific
chat-surface facts that aren't in cortexdj's equivalent:
- UI-only / no Core server-side; route.ts is a proxy
- ChatMessage<CustomUIDataTypes> generic threaded through useChat
- Interactive blocks render off part.type === 'data-<name>' in
  message.tsx::DataPartRenderer (NOT 'tool-<name>' like cortexdj —
  samplespace agents emit data parts, not tool-typed parts)
- ChatActionsProvider supplies sendMessage to descendants
- Heads-up: chat.tsx still uses pre-v5 useChat shape while the local
  docs now document v5/v6 — don't pattern-match new code off the docs
  without checking what chat.tsx does. Migration is its own PR.

No Modal rule mirrored — samplespace doesn't use Modal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code-review findings from the rules-setup branch:

1. The 'chat surface still uses the pre-v5 useChat shape' heads-up was
   factually wrong — that line was pattern-matched from cortexdj's PR
   description, which described cortexdj's codebase, not samplespace's.
   samplespace's chat.tsx already uses DefaultChatTransport + sendMessage
   (no handleInputChange / handleSubmit / 'input' field from useChat).
   Replaced the bullet with a positive description of the actual API in
   use so future Claude can pattern-match safely off chat.tsx. Same fix
   applied to the CLAUDE.md router pointer.

2. ChatMessage signature drift: 'UIMessage<never, CustomUIDataTypes>' →
   'UIMessage<Record<string, never>, CustomUIDataTypes>' (matches
   lib/types.ts). Added a parenthetical explaining the metadata slot
   is intentionally empty, not 'never', so a future Claude doesn't
   'fix' the type to match a stale rule.

3. CustomUIDataTypes has six entries, not five — 'chat-title' is a
   non-rendering data part handled by data-stream-handler.tsx for
   sidebar refresh. Reworked the 'two places' rule to scope to
   *renderable* blocks and note where non-rendering deltas go.

4. Backend route is /api/agent/chat, not /agent/chat (API_PREFIX='/api'
   plus router prefix='/agent'). Fixed in three places:
   CLAUDE.md Frontend section, CLAUDE.md Data Flow #1, and
   vercel-ai-sdk.md's 'AI SDK UI only' bullet.

5. 'render them as code-fence-style blocks' was legacy framing —
   DataPartRenderer invokes block components directly with a
   JSON-stringified code prop, no markdown fence parsing involved.
   Changed to 'render inline in the message stream'.

Verified against chat.tsx, lib/types.ts, message.tsx,
data-stream-handler.tsx, core/config.py, and routers/agent.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@LukeMainwaring LukeMainwaring merged commit 3ad5e51 into main May 13, 2026
3 checks passed
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