Skip to content

Overhaul docs IA, ship AGENTS.md for bundled docs, add eval harness#13

Merged
KayleeWilliams merged 13 commits into
mainfrom
KayleeWilliams/improve-docs
May 9, 2026
Merged

Overhaul docs IA, ship AGENTS.md for bundled docs, add eval harness#13
KayleeWilliams merged 13 commits into
mainfrom
KayleeWilliams/improve-docs

Conversation

@KayleeWilliams
Copy link
Copy Markdown
Collaborator

Summary

Three big strands shipped together over this branch.

1. Docs IA rewrite (Get Started → Authoring → Build → Reference)

Full rewrite of /docs/*.mdx with two hero paths called out from the landing page (build a docs site / bundle docs into a package), seven mermaid diagrams carrying the conceptual load, and tighter prose throughout. Companion changes:

  • New pages: quickstart.mdx, how-it-works.mdx, authoring/frontmatter.mdx, build/validate-in-ci.mdx, reference/cli.mdx.
  • Existing pages reorganized into authoring/, build/, reference/ subdirs.
  • apps/example route files moved to mirror the new IA.
  • Top-level README.md and packages/leadtype/README.md aligned with the new narrative.
  • Steps component restyled (connected numbered circles + tightened typography).
  • vite.config.ts patches setHeader to append ; charset=utf-8 to text/markdown responses (fixes UTF-8 mojibake on .md pages).

2. AGENTS.md instead of llms.txt for npm-bundled docs

llms.txt is a website spec — it assumes a hosted root and absolute URLs. Inside an npm tarball it's the wrong shape: every link is useless offline, and no major coding agent looks for node_modules/<pkg>/llms.txt. The actual filesystem convention is AGENTS.md, supported by 25+ tools (Claude Code, Codex, Cursor, Copilot, Aider, etc.).

  • New generateAgentsMd API in leadtype/llm — same shape as generateLlmsTxt but emits Markdown with relative ./docs/<topic>.md paths.
  • New --bundle flag on leadtype generate — produces AGENTS.md + docs/*.md, skips llms.txt / llms-full* / search artifacts.
  • packages/leadtype/AGENTS.md ships in the published tarball.
  • Docs pages updated everywhere to describe the AGENTS.md flow + the consuming-project pattern (your project's root AGENTS.md points at node_modules/<pkg>/AGENTS.md, à la Next.js).
  • New --bundle integration test in cli.test.ts. Existing 96 tests unchanged. 98/98 pass.

3. Custom AI SDK eval harness for AGENTS.md discoverability

We tried @vercel/agent-eval first; its hardcoded Docker image runs apt-get update && apt-get install ca-certificates git per fresh container, which routinely blows past the 300s timeout under concurrent load. Pivoted to a custom harness on the AI SDK that:

  • Routes through Vercel AI Gateway (AI_GATEWAY_API_KEY only — no separate provider keys).
  • Spins up an OS tempdir per (fixture × mode), no Docker.
  • Defines six tools — read, write, list, glob, grep, plus a narrow npm (subcommand allowlist: pack, install; flag-form args only; scrubbed env). No bash tool. Every tool path-scopes via resolveScoped at the JS level — no shell parsing, no command substitution, no env-var leak.
  • Records every tool call into a transcript JSON; EVAL.ts files assert against it.
  • Archives transcripts + modified files to evals/results/<fixture>/<mode>/<timestamp>-runN/ for debugging.
  • Path-escape unit tests (9/9 pass) verify resolveScoped rejects ..-style escapes and absolute paths.
  • Smoke run on wire-content-negotiation/treatment with claude-haiku-4-5 confirmed the harness works end-to-end (49 tool calls, agent reads AGENTS.md).

Test plan

  • bun test — all 98 leadtype tests pass.
  • bun run --filter leadtype build — clean. AGENTS.md generated at package root.
  • npm pack --dry-run from packages/leadtype/ — tarball includes AGENTS.md and every docs/**/*.md. No llms.txt, no llms-full*, no search-*.json.
  • bun --cwd apps/example run check-types — clean.
  • bun --cwd apps/example run pipeline:build — website mode unchanged, produces public/llms.txt, public/docs/llms-full/*.txt, public/docs/search-index.json, etc.
  • node packages/leadtype/dist/cli.js lint docs --error-unknown — all 15 files pass.
  • bun x ultracite check — clean across the repo.
  • cd evals && bun test lib — 9/9 path-escape and tool unit tests pass.
  • Smoke run: cd evals && bun run evals -- --fixture wire-content-negotiation --mode treatment --runs 1 — harness completes end-to-end.
  • Full eval matrix — left for follow-up. Treatment-vs-control delta is the actual measurement of AGENTS.md value; this PR ships the harness, not the results.

🤖 Generated with Claude Code

- Redirect / to /docs via beforeLoad and remove the Home dashboard
- Add a robot-icon "View as Markdown" toggle in the header that opens
  the agent-friendly .md variant of the current docs page
- Wire pipeline:convert into dev/build so leadtype's convertAllMdx
  populates apps/example/public/docs/**/*.md before vite starts
- Add a Vite middleware that negotiates Accept: text/markdown on
  /docs/* URLs so agents can hit canonical URLs with the right header
- Render Mermaid client-side with @streamdown/mermaid; flatten the
  inner Streamdown chart wrapper so it shows as a single card
- Restructure /docs/components into one section per component
  (description + usage + live example) so the page is a real
  reference and dogfoods the renderer + remark conversion at once
- Wire the NotFound component into router + root route, and update
  it to point users back to /docs
Full rewrite of /docs into Get Started → Authoring → Build → Reference.
Adds quickstart, how-it-works, frontmatter, validate-in-ci, and CLI
reference pages. Every page leads with the problem it solves; mermaid
diagrams carry the conceptual load (headline flow, pipeline internals,
group resolution, plugin order, both build journeys). READMEs aligned
with the new narrative.

Anchor `build` in .gitignore to repo root so docs/build/ and route
build/ directories aren't shadowed by the generic build-output rule.
Updates CLI integration tests to match the new IA (build/ replaces
guides/).
Vite served .md files as `text/markdown` with no charset, so browsers
defaulted to Latin-1 and rendered UTF-8 box-drawing as mojibake
(├── as ├──). The middleware now patches setHeader on every
response to append `; charset=utf-8` to text/markdown and text/plain
when the charset is missing. Covers both negotiated /docs/foo and
direct /docs/foo.md paths.
Adds a Callout warning to the content-negotiation section calling out
that static handlers default to no charset, which makes browsers fall
back to Latin-1 and render UTF-8 as mojibake. Verify step now checks
for charset=utf-8 explicitly.
Agents reading bundled docs (via npm install or llms.txt) can't follow
links to apps/example/* on GitHub, so every "see this file" reference
became a dead end. The connect-docs-site, bundle-package-docs, cli,
llm, remark, components, and quickstart pages now contain the actual
copyable code (mdx-convert script, full vite middleware with charset
patch, generate-docs script, navigation write helpers) rather than
GitHub-link breadcrumbs.
leadtype's bundled docs (inside the published tarball) were emitting
website-shaped artifacts: llms.txt with absolute URLs, llms-full.txt,
search-index.json — none of which made sense at node_modules/<pkg>/.
The llms.txt spec is for hosted websites; agents don't auto-discover
node_modules/<pkg>/llms.txt. The actual filesystem convention is
AGENTS.md, supported by 25+ coding agents (Claude Code, Codex, Cursor,
Copilot, Aider, etc.).

Changes:

- New `generateAgentsMd` in leadtype/llm — same shape as
  generateLlmsTxt but emits Markdown with relative ./docs/<topic>.md
  paths so the file works inside an installed npm package.
- New `--bundle` flag on `leadtype generate`. Emits AGENTS.md +
  docs/*.md and skips llms.txt, llms-full*, and search artifacts.
  Website mode is unchanged.
- packages/leadtype now uses --bundle for its own published tarball.
  AGENTS.md added to package.json#files.
- Docs rewritten across index, how-it-works, quickstart, the bundle
  guide, both READMEs, and the cli + llm references. The "agents read
  llms.txt from node_modules" claim is replaced everywhere with the
  correct AGENTS.md flow plus the Next.js consuming-project pattern.
- New evals/ directory using @vercel/agent-eval to measure
  discoverability empirically: paired bundled-docs vs
  bundled-docs-control experiments across four fixtures
  (wire-content-negotiation, validate-in-ci, explain-cli-flag,
  bundle-own-docs). Pass-rate delta = the value of shipping AGENTS.md.
- New `--bundle` integration test in cli.test.ts asserts AGENTS.md is
  written, llms.txt is NOT, and docs/*.md still ship. Existing tests
  unchanged. 98/98 pass.

Tarball check (`npm pack --dry-run`):
  - AGENTS.md (3.6kB) at root ✓
  - docs/**/*.md (15 files) ✓
  - no llms.txt, no llms-full, no search-index.json ✓
agent-eval's Docker sandboxes were unworkable here: every fresh
node:24-slim container ran apt-get update + apt-get install -y
ca-certificates git before the agent could start, and the framework's
hardcoded image meant we couldn't skip it. With multiple containers
spinning up concurrently apt-get saturated bandwidth and routinely ran
past the 300s timeout. We watched 48 sandboxes hit timeout with zero
transcripts produced and 35+ stuck containers.

The whole isolation layer was overkill for our threat model — these are
our own fixtures. Switched to a custom harness on the AI SDK that:

- Uses Vercel AI Gateway (single AI_GATEWAY_API_KEY for all providers)
- Spins up an OS tempdir per (fixture × mode), no Docker
- Defines six AI SDK tools — read/write/list/glob/grep + a narrow npm
  with subcommand allowlist (pack/install only) and scrubbed env. No
  `bash` tool. Every tool path-scopes via resolveScoped() at the JS
  level — no shell parsing, no command substitution, no env-var leak
- Records every tool call into a transcript JSON the EVAL.ts files
  read via TRANSCRIPT_PATH env var
- Archives transcripts + modified files to evals/results/<fixture>/<mode>/
  for debugging

Smoke run on wire-content-negotiation with claude-haiku-4-5 confirms
the harness works end-to-end: agent runs in 246s, makes 49 tool calls,
reads node_modules/leadtype/AGENTS.md and follows it to write a correct
vite.config.ts. The harness correctly catches that Haiku didn't
navigate from AGENTS.md to the connect-docs-site topic — it skipped to
quickstart.md and improvised. That's the kind of measurement we wanted.

Path-escape unit tests (lib/tools.test.ts) verify resolveScoped rejects
../../../etc/passwd, /etc/passwd, and subdir/../.. — 9/9 pass.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0559b1d8-0680-4a50-8e91-afc3ad3d1122

📥 Commits

Reviewing files that changed from the base of the PR and between 680cca8 and fd59e7e.

📒 Files selected for processing (1)
  • packages/leadtype/.gitignore
📜 Recent review details
🧰 Additional context used
🔍 Remote MCP Context7

Summary of additional factual context useful for reviewing the PR

  • Vite plugin middleware ordering

    • configureServer runs during plugin install; middleware added directly via server.middlewares.use(...) in configureServer executes before Vite’s internal middlewares. Returning a function from configureServer registers a post-install hook whose middleware runs after Vite’s internal middlewares are installed. configurePreviewServer supports the same post-install return pattern for preview server middleware. (Use post hook if you need middleware to run after Vite’s static-file handling or to observe/modify responses Vite produced.)
  • Content-Type / header mutation implications for the plugin in this PR

    • To ensure text/markdown responses served or rewritten by the plugin include a charset, apply header mutation in middleware that runs after Vite’s static-file middleware (post-install hook) so you reliably observe/set the final response Content-Type (examples and guidance in Vite docs).
  • TanStack Router not-found behavior (relevant to added NotFound + router default)

    • Routes may define per-route notFoundComponent; createRootRoute supports notFoundComponent. createRouter accepts defaultNotFoundComponent as a router-wide fallback. Throwing notFound() in a loader triggers the nearest route-level notFoundComponent, or the router defaultNotFoundComponent if no nearer handler exists. Using both a root route notFoundComponent and a router.defaultNotFoundComponent (as this PR does) is a documented and supported pattern.
  • Vercel AI SDK tool() / Zod pattern (relevant to evals scoped tools)

    • Tools are created with tool({ description, inputSchema: z.object({...}), execute: async (...) => ... }) and passed to generateText (or equivalent). The SDK validates tool inputs with the provided Zod schema and returns toolResults / tool call metadata alongside generated text; examples show the exact shape used in the PR (zod inputSchema + execute function). This matches the evals implementation pattern of tool(...) + zod schemas and recorded tool calls.

Tools/sources used

  • Context7 resolve + docs queries for Vite, TanStack Router, and Vercel AI SDK ([Context7_resolve-library-id], [Context7_query-docs]).,
🔇 Additional comments (1)
packages/leadtype/.gitignore (1)

3-5: Looks correct: generated AGENTS artifact is now safely excluded from VCS.

Line 5 (/AGENTS.md) matches the documented generation flow and prevents accidental commits of build-generated package docs.


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added --bundle mode to generate AGENTS.md for offline npm package distribution.
    • Implemented content negotiation to serve markdown to agents via Accept: text/markdown headers.
  • Documentation

    • Reorganized guides into clearer sections: Quickstart, Build, and Reference.
    • Added comprehensive documentation for the generation pipeline, CLI reference, and bundling workflows.
  • UI/UX

    • Enhanced step component styling with visual connectors.
    • Added 404 page with home navigation.
    • Updated navigation structure to reflect new documentation organization.
  • Chores

    • Added evaluation framework for measuring agent discovery of bundled documentation.

Walkthrough

This PR restructures leadtype's documentation pipeline and example app to support offline agent bundles via a new --bundle mode, implements HTTP content negotiation for serving markdown to agents, reorganizes docs into a /build, /reference, /authoring hierarchy, and introduces a comprehensive agent evaluation framework to measure whether coding agents discover and use bundled documentation.

Changes

Bundle Mode & Agent Documentation

Layer / File(s) Summary
Core CLI & API
packages/leadtype/src/cli/generate.ts, packages/leadtype/src/llm/llm.ts, packages/leadtype/src/llm/index.ts
generateAgentsMd() function added to create AGENTS.md at package root with relative links to flattened docs; GenerateArgs and GenerateResult types updated to include bundle flag and mode discriminator; CLI branching logic routes --bundle to generateAgentsMd and skips website/search artifacts.
Build Scripts & Tests
packages/leadtype/scripts/generate-docs.ts, packages/leadtype/src/cli.test.ts, packages/leadtype/.gitignore
Package build script refactored to validate groups up-front, clear root AGENTS.md, and emit bundle output; CLI tests updated to expect /docs/build/ artifacts and new generate --bundle JSON output assertions; gitignore extended for AGENTS.md.
Package Publication
packages/leadtype/package.json
files array includes AGENTS.md for npm publishing.

Content Negotiation & Markdown Serving

Layer / File(s) Summary
Vite Middleware Plugin
apps/example/vite.config.ts
New markdownNegotiation() plugin detects Accept: text/markdown requests under /docs, rewrites to .md files, and forces charset=utf-8 on text responses via response header interception.
Example App Integration
apps/example/package.json, apps/example/playwright.config.ts, apps/example/src/components/site-header.tsx
Dev/preview scripts updated to use portless run with explicit PORTLESS_PORT=1355 and PORTLESS_HTTPS=0; Playwright config adds HTTP port constant and env overrides for portless CLI invocation; site header computes and renders "View as Markdown" external link for /docs paths via markdownHrefForPath().

Documentation Restructuring & Routing

Layer / File(s) Summary
Route Tree & Navigation
apps/example/src/routeTree.gen.ts, apps/example/src/lib/docs.ts, apps/example/src/router.tsx, apps/example/src/routes/__root.tsx
Generated route tree adds /docs/quickstart, /docs/how-it-works, /docs/reference/{cli,convert,lint,llm,remark,search}, /docs/build/{bundle-package-docs,connect-docs-site,validate-in-ci}, and /docs/authoring/{components,frontmatter} while removing old /docs/{search,remark,llm,lint,convert,components,guides/*}; navigation routes removes "Home" entry; root route wires NotFound component for 404 fallback.
Route Handlers
apps/example/src/routes/docs/{quickstart,how-it-works}.tsx, apps/example/src/routes/docs/reference/{cli,convert,lint,llm,remark,search}.tsx, apps/example/src/routes/docs/build/{bundle-package-docs,connect-docs-site,validate-in-ci}.tsx, apps/example/src/routes/docs/authoring/{components,frontmatter}.tsx, apps/example/src/routes/index.tsx, apps/example/src/routes/docs/search.tsx
New route files created for reorganized doc hierarchy; / route redirects to /docs via beforeLoad; old /docs/search.tsx removed.
Documentation Content
docs/{authoring,build,reference}/*.mdx, docs/{quickstart,how-it-works,index,methodology}.mdx, docs/docs.config.ts
Removed old docs/{components,convert,lint,llm,remark,search}.mdx and docs/guides/*.mdx; added new docs under /authoring, /build, /reference with comprehensive API references and guides; docs.config.ts navigation groups restructured to get-started, authoring, build, reference; docs/index.mdx rewritten to focus on pipeline framing with Mermaid flowchart.

UI Components & Styling

Layer / File(s) Summary
Component Updates
apps/example/src/components/{not-found,docs-mdx/mermaid,docs-mdx/command-tabs,site-footer}.tsx
NotFound component added for 404 page layout; Mermaid component refactored to render via Streamdown with @streamdown/mermaid plugin; CommandTabs removes legend element; site footer GitHub link updates to https://github.com/inthhq/leadtype.
Styling
apps/example/src/styles.css
.docs-prose selectors narrowed with :not() guards for step-related elements; [data-leadtype-steps] and [data-leadtype-step] rewritten with CSS counters for numbered, vertically-connected step visualization; [data-leadtype-step]::before/::after pseudo-elements add circle badges and connector lines; [data-leadtype-mermaid] styling simplified with targeted child overrides.

Agent Evaluation Framework

Layer / File(s) Summary
Infrastructure & Sandbox
evals/lib/{sandbox,transcript}.ts, evals/lib/tools.test.ts
SandboxHandle type and createSandbox() create isolated temp directories, copy fixtures, run npm install with leadtype tarball, and support control-mode docs stripping; Transcript types and readTranscript()/writeTranscript() persist tool-call history.
Scoped Toolset
evals/lib/tools.ts
resolveScoped() constrains tool file paths within temp directory; scopedTools() exports {read, write, list, glob, grep, npm} tools with recorded() wrapper for transcript entry logging and result capture.
Evaluation Fixtures
evals/evals/{bundle-own-docs,explain-cli-flag,validate-in-ci,wire-content-negotiation}/{PROMPT.md,EVAL.ts,package.json}
Four evaluation fixtures with LLM prompts and Vitest assertion harnesses: bundle-own-docs verifies agent generates and publishes AGENTS.md; explain-cli-flag tests agent documents --enrich-git behavior; validate-in-ci checks GitHub Actions linting workflow creation; wire-content-negotiation validates Vite markdown negotiation middleware.
Runner & Configuration
evals/run-eval.ts, evals/package.json, evals/.env.example, evals/README.md
run-eval.ts CLI orchestrates fixture discovery, sandbox creation per treatment/control mode, agent execution via generateText with scoped tools, transcript writing, Vitest evaluation, and per-run/cross-fixture result reporting; evals/package.json declares dev dependencies and scripts; .env.example documents AI_GATEWAY_API_KEY; README.md explains harness design and usage.

Configuration & Documentation

Layer / File(s) Summary
Meta Configuration
.gitignore, biome.jsonc, README.md, packages/leadtype/README.md
Root .gitignore anchors /build rule and adds .gstack/ and evals/ patterns; biome.jsonc adds evals/** overrides disabling performance and style rules; root and package READMEs rewritten to emphasize pipeline framing and condense examples.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as Coding Agent
    participant Pkg as npm Package
    participant Vite as Vite Dev Server
    participant FS as Filesystem

    Agent->>Pkg: Read AGENTS.md
    Agent->>Pkg: Follow relative links to docs
    Agent->>Vite: GET /docs/quickstart (markdown accept)
    Vite->>Vite: markdownNegotiation() intercepts
    Vite->>FS: Rewrite to /docs/quickstart.md
    FS-->>Vite: Return markdown content
    Vite->>Vite: Inject charset UTF-8
    Vite-->>Agent: markdown content
    Agent->>FS: Modify package.json
    Agent->>FS: Create docs directory
Loading
sequenceDiagram
    participant CLI as leadtype CLI
    participant LLM as LLM Module
    participant FS as Filesystem

    CLI->>CLI: Parse --bundle flag
    alt Bundle Mode
        CLI->>LLM: generateAgentsMd(config)
        LLM->>FS: Read source docs frontmatter
        LLM->>LLM: Build group membership
        LLM->>FS: Write AGENTS.md at root
        FS-->>LLM: output path
        LLM-->>CLI: bundle result
    else Site Mode
        CLI->>LLM: generateLlmsTxt and search
        LLM-->>CLI: site result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • inthhq/docs#11: Both PRs perform docs-app restructuring, add content-negotiation Vite middleware, update route trees, and implement AGENTS.md/bundle generation—directly overlapping code refactoring and new feature integration.
  • inthhq/leadtype#8: Both PRs move app-owned MDX components out of shared package into consuming examples and update corresponding docs/imports—related architectural refactoring.
  • inthhq/docs#2: Both PRs implement bundled agent docs generation (AGENTS.md, relative links) and content-negotiation markdown serving—directly related feature development.

Poem

🐰 A hop through the docs, a bundle so neat,
Agents now learn the complete treatment—
Markdown served fresh with UTF-8 flair,
Steps numbered and lined with the utmost care,
From guides to reference, the path gleams bright,
Leadtype's pipeline set just right!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be8b4a6f22

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread evals/package.json
"scripts": {
"evals": "bun run run-eval.ts",
"test": "vitest run lib",
"pack-leadtype": "mkdir -p .tarballs && cd ../packages/leadtype && npm pack --pack-destination ../../evals/.tarballs"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Build the package before packing it for evals

When someone follows evals/README.md from a clean checkout and runs bun run pack-leadtype, this script calls npm pack without first running the leadtype build/docs generation. packages/leadtype/docs/ is gitignored and not present in the repo, so the tarball installed by the treatment harness contains AGENTS.md with links to ./docs/... but no bundled docs for agents to read, causing the AGENTS.md discovery evals that assert topic reads to fail unless the developer happened to build the package manually beforehand.

Useful? React with 👍 / 👎.

Comment thread evals/lib/tools.ts
Comment on lines +233 to +235
const matches = await fg(pattern, {
cwd: tempDir,
absolute: false,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope glob patterns before running fast-glob

The harness claims every tool path-scopes through resolveScoped, but the glob tool passes the model-controlled pattern directly to fast-glob. For patterns that include parent segments or absolute roots, this bypasses the tempdir check used by read, write, list, and grep, so an agent can enumerate paths outside the sandbox even though the eval README says it cannot see outside the tempdir.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/example/src/components/site-header.tsx`:
- Around line 34-45: The markdownHrefForPath helper incorrectly maps "/docs/" to
"/docs.md" because it checks for the root "/docs" before normalizing trailing
slashes; fix by normalizing the pathname up front (use TRAILING_SLASH_PATTERN to
strip trailing slash into a local variable, e.g., normalized) and then perform
the checks against normalized: if normalized is not under "/docs" return null,
if normalized endsWith(".md") return null, if normalized === "/docs" return
"/docs/index.md", otherwise return `${normalized}.md`. Update all references in
markdownHrefForPath to use the normalized variable.

In `@apps/example/vite.config.ts`:
- Around line 65-79: The monkeypatch in forceUtf8OnTextResponses currently binds
res.setHeader to original and assumes string arguments; update the patch to
preserve all overloads and this context by capturing the original as done
(original = res.setHeader.bind(res)) but implement the wrapper using a rest-args
signature (e.g., (...args)) and call the original via Reflect.apply(original,
res, args) so return value and this are preserved; additionally, handle
non-string/array header values safely by checking types before modifying value
(only modify when name is a string equal to "content-type" and value is a string
matching TEXT_CONTENT_TYPE_PATTERN without CHARSET_PATTERN), otherwise delegate
to original unchanged.

In `@biome.jsonc`:
- Around line 39-42: Update the stale rationale comment that references
"@vercel/agent-eval" so it accurately describes the current eval architecture:
replace the mention of `@vercel/agent-eval` with the "custom AI SDK harness" and
keep the guidance about fixture naming (EVAL.ts and PROMPT.md) and lint
decisions (useTopLevelRegex / useConsistentTypeDefinitions) intact; specifically
edit the comment containing the string "@vercel/agent-eval" and the lines
referencing "EVAL.ts", "PROMPT.md", and "useTopLevelRegex /
useConsistentTypeDefinitions" to reflect the new harness and avoid confusion.

In `@docs/build/connect-docs-site.mdx`:
- Line 184: Update the prose around the CLI flag so the platform name is
correctly capitalized: keep the flag text exactly as `--format github` but
change the surrounding plain-text reference to the platform to “GitHub” (capital
H) in the sentence that currently reads "Use `--format github` in CI to get
inline annotations on the PR."

In `@docs/how-it-works.mdx`:
- Around line 144-150: The documentation for the leadtype generate command
currently describes mode-specific outputs as if they always occur (it hardcodes
the converted output path `public/docs/` and implies LLM bundle/search
generation always runs); update the step list under the "leadtype generate"
command to be mode-agnostic by: (1) changing the fixed `public/docs/` reference
to a conditional phrase like "site output (e.g. public/docs/) when running site
mode", (2) clarifying that "Generate LLM bundles" and "Build the search index"
only run when the corresponding flags/modes (e.g. `--bundle` / bundle or search
mode) are enabled, and (3) mention the flag names (`--bundle`) and/or mode names
so readers know these steps are conditional rather than universal.

In `@evals/evals/explain-cli-flag/EVAL.ts`:
- Around line 11-13: The code uses a type assertion (c.args.path as string) when
building reads from transcript.toolCalls; instead, narrow the type by checking
that c.args && typeof c.args.path === "string" (or by filtering entries where
typeof c.args?.path === "string") before mapping, so reads only contains actual
strings and you can remove the unsafe as string assertion while keeping the
fallback logic for missing values; update the filter/map on transcript.toolCalls
(the reads assignment) to perform this runtime type check.

In `@evals/evals/explain-cli-flag/PROMPT.md`:
- Line 1: Add a top-level H1 heading as the first line of PROMPT.md to satisfy
markdownlint MD041; prepend a concise H1 (e.g., "# Explanation of --enrich-git")
above the existing paragraph so the file begins with an H1 and then the current
instruction sentence remains unchanged.

In `@evals/evals/validate-in-ci/PROMPT.md`:
- Line 1: The file PROMPT.md triggers MD041 because it starts with body text;
add a top-level H1 heading at the top of PROMPT.md (for example, "# Prompt" or a
concise title relevant to the content) so the file begins with an H1 line and
the existing content follows; this will satisfy the markdownlint rule without
changing the rest of the text.

In `@evals/evals/wire-content-negotiation/EVAL.ts`:
- Around line 40-55: Both tests duplicate reading vite.config.ts; extract a
helper (e.g., getViteConfigSource) at the top of the describe block that builds
viteConfigPath using projectRoot, asserts existsSync(viteConfigPath) and returns
readFileSync(viteConfigPath, "utf-8"), then replace the inline file-read logic
in the "middleware sets charset=utf-8" and "middleware rewrites /docs/* paths to
.md" tests to call getViteConfigSource() and run the same expect assertions
against its returned string.

In `@evals/evals/wire-content-negotiation/PROMPT.md`:
- Line 1: Add a top-level H1 as the very first line of PROMPT.md to satisfy
markdown linting (MD041); insert a single heading like "# Title" or a brief
descriptive H1 above the existing content so the file begins with an H1 and the
markdown linter stops flagging the prompt.

In `@evals/lib/sandbox.ts`:
- Around line 45-51: The cp call inside createSandbox can fail
(permissions/symlinks); wrap the cp(fixtureDir, tempDir, ...) invocation in a
try/catch, catch the error, and augment it with a clear diagnostic message that
includes fixtureDir and tempDir (or log via the existing logger) before
rethrowing or throwing a new Error that preserves the original error/stack; this
will make failures in cp easier to diagnose while still letting callers handle
the error.

In `@evals/run-eval.ts`:
- Around line 51-53: The CLI parsing for "--runs" currently sets args.runs =
Number.parseInt(...) without validating, allowing 0 or NaN; update the parsing
logic (the argv handling where args.runs is assigned and the other similar
occurrences around lines referencing args.runs) to verify the parsed value is an
integer > 0 (e.g., Number.isFinite and Number.isInteger checks and > 0), and if
invalid print a clear error to stderr and exit with a non-zero code (or default
to 1 explicitly), ensuring downstream summary math never runs with 0 or NaN
runs.
- Around line 274-291: The promise returned by runVitest can hang if spawn fails
or the child emits an 'error' event; update the code around the spawn call (the
proc variable created by spawn in runVitest) to (1) wrap spawn in try/catch and
immediately resolveSpawn with { passed: false, output: err.message } if spawn
throws, and (2) attach an 'error' listener on proc that resolves (or rejects)
the Promise with a failure result and include the error message in output;
ensure you still only resolve once (use a flag or remove other listeners) and
keep the existing stdout/stderr and 'close' handling intact.
- Around line 185-220: Wrap the main run logic (including the call to runVitest,
processing of evalResult, printing output, and the await archiveTranscript call)
in a try block and move the sandbox.cleanup() call into a finally block so
cleanup always runs even if runVitest or archiveTranscript throws; specifically,
keep await archiveTranscript({...}) inside the try but ensure finally { await
sandbox.cleanup(); } is present, referencing the existing runVitest,
archiveTranscript, and sandbox.cleanup symbols.

In `@packages/leadtype/README.md`:
- Around line 39-45: Replace the placeholder docs domain
"https://docs.example.com" used across the README: update the five links in the
docs list (the Quickstart, How it works, Build a docs site, Bundle docs into a
package, and CLI reference) and also update the example command that references
the example docs URL (the example command on line 13) to the real production
docs domain once it's available; search for the string "docs.example.com" in the
README and substitute the canonical production docs hostname so all links point
to the live documentation.

In `@packages/leadtype/src/cli.test.ts`:
- Around line 387-390: The bundle-mode test in cli.test.ts currently only
asserts that "search-index.json" is not emitted; update the test to also assert
that "search-content.json" is not emitted by adding a second expectation using
the same pattern (use existsSync and path.join with outDir and "docs" to check
"search-content.json") and assert toBe(false) so regressions that emit the full
search content will fail; locate the check near the existing
expect(existsSync(path.join(outDir, "docs", "search-index.json"))).toBe(false)
and add the analogous assertion for "search-content.json".

In `@README.md`:
- Around line 30-63: Replace the placeholder docs host
"https://docs.example.com" used across the README (including the 30-second
example commands and links to Quickstart, How it works, Frontmatter, CLI
reference, Methodology, and the two example outputs like AGENTS.md/llms.txt)
with the real documentation origin or repository-relative paths; update the npx
generate examples to use the real --base-url or remove the host so they work
locally, and ensure all user-facing links point to live docs or relative URLs
before merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f68611d3-0753-45a2-8470-381e0dbad623

📥 Commits

Reviewing files that changed from the base of the PR and between bfccdc2 and be8b4a6.

⛔ Files ignored due to path filters (5)
  • apps/example/src/generated/docs-nav.json is excluded by !**/generated/**
  • apps/example/src/generated/docs-search-content.json is excluded by !**/generated/**
  • apps/example/src/generated/docs-search-index.json is excluded by !**/generated/**
  • bun.lock is excluded by !**/*.lock
  • evals/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (84)
  • .gitignore
  • README.md
  • apps/example/package.json
  • apps/example/playwright.config.ts
  • apps/example/src/components/docs-mdx/command-tabs.tsx
  • apps/example/src/components/docs-mdx/mermaid.tsx
  • apps/example/src/components/not-found.tsx
  • apps/example/src/components/site-footer.tsx
  • apps/example/src/components/site-header.tsx
  • apps/example/src/lib/docs.ts
  • apps/example/src/routeTree.gen.ts
  • apps/example/src/router.tsx
  • apps/example/src/routes/__root.tsx
  • apps/example/src/routes/docs/authoring/components.tsx
  • apps/example/src/routes/docs/authoring/frontmatter.tsx
  • apps/example/src/routes/docs/build/bundle-package-docs.tsx
  • apps/example/src/routes/docs/build/connect-docs-site.tsx
  • apps/example/src/routes/docs/build/validate-in-ci.tsx
  • apps/example/src/routes/docs/how-it-works.tsx
  • apps/example/src/routes/docs/quickstart.tsx
  • apps/example/src/routes/docs/reference/cli.tsx
  • apps/example/src/routes/docs/reference/convert.tsx
  • apps/example/src/routes/docs/reference/lint.tsx
  • apps/example/src/routes/docs/reference/llm.tsx
  • apps/example/src/routes/docs/reference/remark.tsx
  • apps/example/src/routes/docs/reference/search.tsx
  • apps/example/src/routes/docs/search.tsx
  • apps/example/src/routes/index.tsx
  • apps/example/src/styles.css
  • apps/example/vite.config.ts
  • biome.jsonc
  • docs/authoring/components.mdx
  • docs/authoring/frontmatter.mdx
  • docs/build/bundle-package-docs.mdx
  • docs/build/connect-docs-site.mdx
  • docs/build/validate-in-ci.mdx
  • docs/components.mdx
  • docs/convert.mdx
  • docs/docs.config.ts
  • docs/guides/bundle-package-docs.mdx
  • docs/guides/connect-docs-site.mdx
  • docs/how-it-works.mdx
  • docs/index.mdx
  • docs/lint.mdx
  • docs/llm.mdx
  • docs/methodology.mdx
  • docs/quickstart.mdx
  • docs/reference/cli.mdx
  • docs/reference/convert.mdx
  • docs/reference/lint.mdx
  • docs/reference/llm.mdx
  • docs/reference/remark.mdx
  • docs/reference/search.mdx
  • docs/remark.mdx
  • docs/search.mdx
  • evals/.env.example
  • evals/README.md
  • evals/evals/bundle-own-docs/EVAL.ts
  • evals/evals/bundle-own-docs/PROMPT.md
  • evals/evals/bundle-own-docs/package.json
  • evals/evals/explain-cli-flag/EVAL.ts
  • evals/evals/explain-cli-flag/PROMPT.md
  • evals/evals/explain-cli-flag/package.json
  • evals/evals/validate-in-ci/EVAL.ts
  • evals/evals/validate-in-ci/PROMPT.md
  • evals/evals/validate-in-ci/package.json
  • evals/evals/wire-content-negotiation/EVAL.ts
  • evals/evals/wire-content-negotiation/PROMPT.md
  • evals/evals/wire-content-negotiation/package.json
  • evals/evals/wire-content-negotiation/vite.config.ts
  • evals/lib/sandbox.ts
  • evals/lib/tools.test.ts
  • evals/lib/tools.ts
  • evals/lib/transcript.ts
  • evals/package.json
  • evals/run-eval.ts
  • packages/leadtype/AGENTS.md
  • packages/leadtype/README.md
  • packages/leadtype/package.json
  • packages/leadtype/scripts/generate-docs.ts
  • packages/leadtype/src/cli.test.ts
  • packages/leadtype/src/cli/generate.ts
  • packages/leadtype/src/llm/index.ts
  • packages/leadtype/src/llm/llm.ts
💤 Files with no reviewable changes (11)
  • apps/example/src/routes/docs/search.tsx
  • docs/llm.mdx
  • apps/example/src/lib/docs.ts
  • docs/lint.mdx
  • docs/guides/bundle-package-docs.mdx
  • docs/remark.mdx
  • docs/convert.mdx
  • docs/guides/connect-docs-site.mdx
  • docs/components.mdx
  • apps/example/src/components/docs-mdx/command-tabs.tsx
  • docs/search.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • apps/example/src/routes/docs/reference/convert.tsx
  • apps/example/src/routes/docs/reference/remark.tsx
  • apps/example/playwright.config.ts
  • apps/example/src/routes/docs/authoring/frontmatter.tsx
  • apps/example/src/routes/docs/reference/llm.tsx
  • apps/example/src/components/site-footer.tsx
  • apps/example/src/routes/docs/build/connect-docs-site.tsx
  • apps/example/src/routes/docs/authoring/components.tsx
  • evals/evals/wire-content-negotiation/vite.config.ts
  • apps/example/src/routes/docs/build/bundle-package-docs.tsx
  • apps/example/src/routes/docs/quickstart.tsx
  • apps/example/src/routes/__root.tsx
  • evals/evals/validate-in-ci/EVAL.ts
  • packages/leadtype/src/llm/index.ts
  • apps/example/src/components/not-found.tsx
  • apps/example/src/routes/docs/reference/cli.tsx
  • evals/evals/explain-cli-flag/EVAL.ts
  • apps/example/src/routes/docs/build/validate-in-ci.tsx
  • apps/example/vite.config.ts
  • evals/lib/transcript.ts
  • apps/example/src/routes/docs/reference/search.tsx
  • evals/lib/sandbox.ts
  • evals/lib/tools.test.ts
  • docs/docs.config.ts
  • apps/example/src/components/site-header.tsx
  • evals/evals/bundle-own-docs/EVAL.ts
  • apps/example/src/routes/index.tsx
  • packages/leadtype/src/llm/llm.ts
  • evals/lib/tools.ts
  • apps/example/src/routes/docs/how-it-works.tsx
  • apps/example/src/routes/docs/reference/lint.tsx
  • evals/run-eval.ts
  • evals/evals/wire-content-negotiation/EVAL.ts
  • apps/example/src/router.tsx
  • apps/example/src/routeTree.gen.ts
  • packages/leadtype/scripts/generate-docs.ts
  • apps/example/src/components/docs-mdx/mermaid.tsx
  • packages/leadtype/src/cli/generate.ts
  • packages/leadtype/src/cli.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • apps/example/src/routes/docs/reference/convert.tsx
  • apps/example/src/routes/docs/reference/remark.tsx
  • apps/example/playwright.config.ts
  • apps/example/src/routes/docs/authoring/frontmatter.tsx
  • apps/example/src/routes/docs/reference/llm.tsx
  • apps/example/src/components/site-footer.tsx
  • apps/example/src/routes/docs/build/connect-docs-site.tsx
  • apps/example/src/routes/docs/authoring/components.tsx
  • evals/evals/wire-content-negotiation/vite.config.ts
  • apps/example/src/routes/docs/build/bundle-package-docs.tsx
  • apps/example/src/routes/docs/quickstart.tsx
  • apps/example/src/routes/__root.tsx
  • evals/evals/validate-in-ci/EVAL.ts
  • packages/leadtype/src/llm/index.ts
  • apps/example/src/components/not-found.tsx
  • apps/example/src/routes/docs/reference/cli.tsx
  • evals/evals/explain-cli-flag/EVAL.ts
  • apps/example/src/routes/docs/build/validate-in-ci.tsx
  • apps/example/vite.config.ts
  • evals/lib/transcript.ts
  • apps/example/src/routes/docs/reference/search.tsx
  • evals/lib/sandbox.ts
  • evals/lib/tools.test.ts
  • docs/docs.config.ts
  • apps/example/src/components/site-header.tsx
  • evals/evals/bundle-own-docs/EVAL.ts
  • apps/example/src/routes/index.tsx
  • packages/leadtype/src/llm/llm.ts
  • evals/lib/tools.ts
  • apps/example/src/routes/docs/how-it-works.tsx
  • apps/example/src/routes/docs/reference/lint.tsx
  • evals/run-eval.ts
  • evals/evals/wire-content-negotiation/EVAL.ts
  • apps/example/src/router.tsx
  • apps/example/src/routeTree.gen.ts
  • packages/leadtype/scripts/generate-docs.ts
  • apps/example/src/components/docs-mdx/mermaid.tsx
  • packages/leadtype/src/cli/generate.ts
  • packages/leadtype/src/cli.test.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use the key prop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
Avoid dangerouslySetInnerHTML unless absolutely necessary
Use proper image components (e.g., Next.js <Image>) over <img> tags
Use Next.js <Image> component for images
Use next/head or App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead of React.forwardRef in React 19+

Files:

  • apps/example/src/routes/docs/reference/convert.tsx
  • apps/example/src/routes/docs/reference/remark.tsx
  • apps/example/src/routes/docs/authoring/frontmatter.tsx
  • apps/example/src/routes/docs/reference/llm.tsx
  • apps/example/src/components/site-footer.tsx
  • apps/example/src/routes/docs/build/connect-docs-site.tsx
  • apps/example/src/routes/docs/authoring/components.tsx
  • apps/example/src/routes/docs/build/bundle-package-docs.tsx
  • apps/example/src/routes/docs/quickstart.tsx
  • apps/example/src/routes/__root.tsx
  • apps/example/src/components/not-found.tsx
  • apps/example/src/routes/docs/reference/cli.tsx
  • apps/example/src/routes/docs/build/validate-in-ci.tsx
  • apps/example/src/routes/docs/reference/search.tsx
  • apps/example/src/components/site-header.tsx
  • apps/example/src/routes/index.tsx
  • apps/example/src/routes/docs/how-it-works.tsx
  • apps/example/src/routes/docs/reference/lint.tsx
  • apps/example/src/router.tsx
  • apps/example/src/components/docs-mdx/mermaid.tsx
**/*.{jsx,tsx,html}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Add rel="noopener" when using target="_blank" on links

Files:

  • apps/example/src/routes/docs/reference/convert.tsx
  • apps/example/src/routes/docs/reference/remark.tsx
  • apps/example/src/routes/docs/authoring/frontmatter.tsx
  • apps/example/src/routes/docs/reference/llm.tsx
  • apps/example/src/components/site-footer.tsx
  • apps/example/src/routes/docs/build/connect-docs-site.tsx
  • apps/example/src/routes/docs/authoring/components.tsx
  • apps/example/src/routes/docs/build/bundle-package-docs.tsx
  • apps/example/src/routes/docs/quickstart.tsx
  • apps/example/src/routes/__root.tsx
  • apps/example/src/components/not-found.tsx
  • apps/example/src/routes/docs/reference/cli.tsx
  • apps/example/src/routes/docs/build/validate-in-ci.tsx
  • apps/example/src/routes/docs/reference/search.tsx
  • apps/example/src/components/site-header.tsx
  • apps/example/src/routes/index.tsx
  • apps/example/src/routes/docs/how-it-works.tsx
  • apps/example/src/routes/docs/reference/lint.tsx
  • apps/example/src/router.tsx
  • apps/example/src/components/docs-mdx/mermaid.tsx
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid barrel files (index files that re-export everything)

Files:

  • packages/leadtype/src/llm/index.ts
  • apps/example/src/routes/index.tsx
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • evals/lib/tools.test.ts
  • packages/leadtype/src/cli.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:25:33.574Z
Learning: Leadtype converts a single MDX source into four artifacts: a website for humans, llms.txt for agents, topic-scoped full-context bundles, and a static search index
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:25:33.574Z
Learning: Validate frontmatter, navigation structure, and internal links before publishing using leadtype lint
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:25:33.574Z
Learning: Ship agent-readable docs inside npm packages so IDEs and coding agents can read documentation offline
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:25:33.574Z
Learning: Use the remark plugin stack to flatten MDX components into markdown that agents can process
🪛 ast-grep (0.42.1)
evals/lib/tools.ts

[warning] 85-85: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(pattern, flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
evals/evals/validate-in-ci/PROMPT.md

[uncategorized] ~1-~1: The official name of this software platform is spelled with a capital “H”.
Context: Add a GitHub Actions workflow at .github/workflows/lint-docs.yml that runs `lea...

(GITHUB)

packages/leadtype/AGENTS.md

[uncategorized] ~54-~54: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...stack that flattens MDX components into markdown. - Search...

(MARKDOWN_NNP)

evals/README.md

[grammar] ~21-~21: Ensure spelling is correct
Context: ... call into a transcript JSON. 6. Spawns vitest against the fixture's EVAL.ts, which ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~23-~23: Ensure spelling is correct
Context: ...terally cannot see anything outside the tempdir. ## Setup ```bash cd evals cp .env.example ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/how-it-works.mdx

[uncategorized] ~33-~33: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...old headings, a <TypeTable> becomes a markdown table. The flattened markdown is what e...

(MARKDOWN_NNP)


[style] ~73-~73: Consider a different adjective to strengthen your wording.
Context: ...t over HTTP and follow absolute URLs to deeper context. Useless inside an npm tarball,...

(DEEP_PROFOUND)

docs/reference/lint.mdx

[uncategorized] ~164-~164: The official name of this software platform is spelled with a capital “H”.
Context: ...ateso content errors fail fast. - Use--format githubin GitHub Actions and--format json` ...

(GITHUB)

docs/authoring/components.mdx

[uncategorized] ~9-~9: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...ipeline can flatten each component into markdown for agents, search, and `llms-full/*.tx...

(MARKDOWN_NNP)


[uncategorized] ~17-~17: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...ne per tab. - A <TypeTable> becomes a markdown table. - A <Mermaid> becomes a fenced...

(MARKDOWN_NNP)


[uncategorized] ~125-~125: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ... install or run commands. Flattens to a markdown table with one row per manager. Use `m...

(MARKDOWN_NNP)

docs/build/bundle-package-docs.mdx

[style] ~77-~77: The double modal “needs shared” is nonstandard (only accepted in certain dialects). Consider “to be shared”.
Context: ...ters are explicit. If the package needs shared overview pages, list them too. `--exclu...

(NEEDS_FIXED)

docs/reference/remark.mdx

[uncategorized] ~51-~51: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...mandTabsToMarkdown→ markdown table. 10.remarkStepsToMarkdown<...

(MARKDOWN_NNP)


[uncategorized] ~54-~54: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...ypeTable>and→ markdown table. 13.remarkAccordionToMarkdown` ...

(MARKDOWN_NNP)


[uncategorized] ~102-~102: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...file, finds the named type, and emits a markdown table with one row per property. The re...

(MARKDOWN_NNP)


[style] ~109-~109: ‘almost never’ might be wordy. Consider a shorter alternative.
Context: ...d the converted .md first. The fix is almost never reordering — it's usually a custom plug...

(EN_WORDINESS_PREMIUM_ALMOST_NEVER)

docs/reference/cli.mdx

[uncategorized] ~109-~109: The official name of this software platform is spelled with a capital “H”.
Context: ...fmt>|pretty|pretty, json, or github(annotation format). | |--ignore <gl...

(GITHUB)

docs/build/validate-in-ci.mdx

[uncategorized] ~24-~24: The official name of this software platform is spelled with a capital “H”.
Context: ...end the schema. ## GitHub Actions Use --format github so violations render as inline annotat...

(GITHUB)


[style] ~79-~79: Consider using a synonym to be more concise.
Context: ... ## What to fix first When CI fails on a lot of violations, fix them in this order: 1....

(A_LOT_OF)

docs/build/connect-docs-site.mdx

[uncategorized] ~184-~184: The official name of this software platform is spelled with a capital “H”.
Context: ...fore the converter writes anything. Use --format github in CI to get inline annotations on the...

(GITHUB)

docs/reference/llm.mdx

[style] ~32-~32: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ened into one file. Use for agents with very large context windows. | | `/docs/llms-f...

(EN_WEAK_ADJECTIVE)

docs/methodology.mdx

[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...sted platform when you want zero infra. Use leadtype when you want to **own the doc...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.22.1)
evals/evals/validate-in-ci/PROMPT.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

evals/evals/explain-cli-flag/PROMPT.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

evals/evals/bundle-own-docs/PROMPT.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

evals/evals/wire-content-negotiation/PROMPT.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

evals/README.md

[warning] 68-68: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 89-89: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔍 Remote MCP Context7

Perfect! Now I have the documentation context. Let me compile a concise summary of the relevant findings for PR review.

Additional Context for PR Review

Based on documentation review of the key libraries used in this PR, here's the relevant validation context:

1. Vite Plugin & Middleware Configuration

The PR's custom leadtype:markdown-negotiation Vite plugin using the configureServer hook follows the documented pattern. According to Vite v7 documentation:

  • The configureServer hook correctly provides access to the dev server instance for custom middleware injection
  • The plugin can return a post-hook that runs after internal middlewares are installed, which is appropriate for intercepting and modifying responses
  • Using server.middlewares.use() to add custom middleware that manipulates response headers (the charset=utf-8 append) is the standard pattern

Key validation: The implementation approach of checking Accept headers and rewriting paths in middleware aligns with Vite's recommended patterns for content negotiation.


2. TanStack Router Routing Structure

The PR restructures routes using createFileRoute with nested paths. Documentation confirms:

  • File-based routing with createFileRoute('/path')({ component: ... }) is the standard pattern
  • NotFound handling: The pattern of setting notFoundComponent on both root route (__root.tsx) and router-level defaultNotFoundComponent matches the documented best practice for not-found errors
  • The PR adds both: a dedicated NotFound component at __root.tsx and a router-level defaultNotFoundComponent: NotFound in router.tsx

Key validation: This dual-layer approach provides proper fallback coverage and aligns with Tanstack Router's documented guidance: "If no suitable handler is found, the root route will handle it with a basic default component. It is highly recommended to configure a notFoundComponent for the root route or a router-wide defaultNotFoundComponent."


3. Vercel AI SDK Tools & Schemas

The PR's eval harness implements scoped tools using the AI SDK's tool system. Documentation confirms the correct pattern:

  • Tools are defined with tool() helper from the ai package
  • Zod schemas are used to validate tool inputs (z.object() with .describe() for field descriptions)
  • The execute function pattern is standard for tool implementation
  • The tools in evals/lib/tools.ts (read, write, list, glob, grep, npm) follow the documented schema and execute function pattern

Key validation: The scoped tool implementation using zod schemas and async execute functions matches the documented Vercel AI SDK approach. The pattern of providing descriptive field descriptions helps guide model behavior—important for agent instructions.


Summary

The PR's implementation of three major components (Vite middleware, TanStack Router structure, and AI SDK tools) all follow documented best practices from their respective libraries:

  1. ✅ Vite plugin middleware approach for content negotiation is correct
  2. ✅ NotFound component routing pattern provides proper error boundary coverage
  3. ✅ Scoped tools implementation with Zod schemas matches AI SDK documentation
🔇 Additional comments (73)
.gitignore (2)

27-27: LGTM: Anchored build pattern improves specificity.

Changing build to /build restricts the ignore to the root-level build directory only, preventing unintended matches in nested paths. This aligns with the PR objectives.


41-45: LGTM: Comprehensive eval artifact exclusion.

The patterns correctly exclude eval harness outputs (tarballs, results, and agent eval directories). Using both evals/__agent_eval__/ and evals/**/__agent_eval__/ provides clarity even though the globstar pattern covers both cases.

apps/example/src/components/site-footer.tsx (1)

3-3: GitHub footer link update looks correct.

This aligns the footer target with the Leadtype repository and preserves the existing external-link safety behavior.

evals/.env.example (1)

1-5: Env template addition is clear and appropriate.

The new key placeholder and comments are concise and useful for harness setup.

evals/package.json (1)

1-18: Eval package manifest is well-structured.

Scripts and dev dependencies are coherent with the custom eval harness workflow.

apps/example/src/routes/docs/reference/llm.tsx (1)

4-7: Route path and MDX source move are correctly aligned.

The updated route target and document import are consistent with the new docs IA location.

docs/build/validate-in-ci.mdx (1)

1-86: Strong CI guidance and clear failure triage flow.

The page is practical, concrete, and gives a clean lint-first workflow for teams.

packages/leadtype/AGENTS.md (1)

1-56: AGENTS.md structure is clear and agent-friendly.

The sectioning and relative topic links make offline navigation straightforward.

apps/example/src/routes/docs/build/validate-in-ci.tsx (1)

1-12: Looks good — route registration and MDX rendering are correctly wired.

evals/evals/validate-in-ci/package.json (1)

1-11: Fixture manifest is clean and fit-for-purpose.

docs/authoring/frontmatter.mdx (1)

1-109: Excellent addition — clear, comprehensive frontmatter and linting guidance.

apps/example/src/routes/docs/authoring/frontmatter.tsx (1)

1-12: Route setup is correct and consistent with the docs IA structure.

evals/evals/explain-cli-flag/package.json (1)

1-11: This fixture package config looks solid.

evals/evals/bundle-own-docs/package.json (1)

1-15: Package fixture configuration is appropriate for the eval scenario.

evals/evals/wire-content-negotiation/package.json (1)

1-12: This fixture manifest is correctly structured for the test harness.

docs/docs.config.ts (1)

3-50: Config rewrite looks consistent with the new IA and artifact narrative.

The updated product copy and top-level groups structure are coherent and release-ready.

apps/example/src/components/not-found.tsx (1)

5-28: 404 component is clean and well integrated.

Layout composition and recovery path back to docs are solid.

docs/reference/lint.mdx (1)

1-169: Comprehensive lint reference—scope and structure are strong.

Rules, API surface, result schema, and CI guidance are clear and actionable.

apps/example/src/routes/docs/reference/lint.tsx (1)

4-8: Route migration is consistent and correctly wired.

The new path and MDX source update match the IA move.

docs/methodology.mdx (1)

9-41: Positioning rewrite is clear and effective.

The ownership boundaries and pairing guidance are easy to follow.

docs/authoring/components.mdx (1)

22-247: Great component-contract documentation depth.

This gives authors a practical, implementation-ready map of flattening behavior.

apps/example/src/routes/docs/authoring/components.tsx (1)

4-8: Authoring route move is correctly implemented.

Path and source doc updates are aligned with the IA restructure.

apps/example/src/routes/docs/how-it-works.tsx (1)

3-12: Route wiring looks good

The new /docs/how-it-works route cleanly maps to the MDX page and follows the existing route-module pattern.

docs/build/bundle-package-docs.mdx (1)

28-165: Solid bundle-mode documentation

This is clear, actionable, and covers both producer and consumer sides of the AGENTS.md workflow well.

apps/example/src/routes/docs/build/bundle-package-docs.tsx (1)

4-8: Import/path migration is correct

The route now points at the new docs location and stays aligned with the restructured IA.

docs/reference/cli.mdx (1)

23-143: CLI reference is thorough and well-structured

The page clearly distinguishes site vs bundle output, documents exit codes, and gives useful JSON-mode behavior details.

apps/example/src/routes/docs/reference/cli.tsx (1)

3-12: Route addition is clean

/docs/reference/cli is wired correctly and renders the new MDX page as expected.

docs/reference/search.mdx (1)

17-153: Search reference is strong

Great coverage of the end-to-end flow (indexing, querying, retrieval helpers, streaming, and guardrails) with practical code examples.

apps/example/src/routes/docs/reference/search.tsx (1)

3-12: Route wiring looks correct and clean.

MDX import, path registration, and route component rendering are all consistent with the docs IA move.

docs/build/connect-docs-site.mdx (1)

8-211: Strong end-to-end build guide.

The flow, middleware example, and verification checklist are clear and actionable.

apps/example/src/routes/docs/build/connect-docs-site.tsx (1)

4-12: Path and import updates are consistent with the new IA.

This correctly re-points both the route and MDX source to the build/ section.

docs/quickstart.mdx (1)

44-87: Quickstart narrative is clear and correctly distinguishes site vs bundle outputs.

The examples and artifact expectations are easy to follow for first-time setup.

apps/example/src/routes/docs/quickstart.tsx (1)

3-12: Route setup is good.

This cleanly exposes the new quickstart page under /docs/quickstart.

packages/leadtype/package.json (1)

62-67: Publishing whitelist update is correct.

Including AGENTS.md in files aligns the npm tarball with the new bundle discovery flow.

evals/evals/wire-content-negotiation/vite.config.ts (1)

1-8: Fixture scaffold is appropriate for the eval scenario.

The minimal config and explicit placeholder make the expected agent edit target clear.

apps/example/src/router.tsx (1)

2-11: Default not-found fallback is a solid addition.

defaultNotFoundComponent wiring is clean and improves global unmatched-route handling.

apps/example/src/routes/__root.tsx (1)

34-34: Explicit root notFoundComponent wiring looks good.

This keeps unmatched-route rendering deterministic at the route definition point.

packages/leadtype/src/llm/index.ts (1)

2-3: Public export surface update is clean and consistent.

Re-exporting generateAgentsMd with its config/result types makes the bundle API discoverable from the module entrypoint.

Also applies to: 11-11

apps/example/src/routes/docs/reference/convert.tsx (1)

4-4: Route path and MDX source relocation are correctly aligned.

This matches the new /docs/reference/* structure without introducing behavior regressions.

Also applies to: 6-6

apps/example/src/routes/docs/reference/remark.tsx (1)

4-4: remark doc route migration is consistent with the new IA.

Import target and route id now match the reference namespace.

Also applies to: 6-6

docs/reference/convert.mdx (1)

21-42: API coverage and plugin-order guidance are clear and implementation-aligned.

The page cleanly documents convertAllMdx options and correctly emphasizes remarkInclude ordering.

Also applies to: 81-92

evals/README.md (2)

68-81: 💤 Low value

Add language specifier to fenced code blocks.

The directory layout and results table code blocks should have a language specifier like text or plaintext for consistency and to satisfy linting.


1-103: LGTM!

The README provides comprehensive documentation of the eval harness, clearly explaining the treatment vs control methodology, setup steps, CLI flags, and how to interpret results. The technical terms flagged by static analysis (vitest, tempdir) are correct.

apps/example/src/components/docs-mdx/mermaid.tsx (1)

1-20: LGTM!

The refactor from a static placeholder to Streamdown-based rendering is clean. The client component correctly uses the mermaid plugin, and the fallback to empty string for non-string children handles edge cases gracefully.

evals/evals/bundle-own-docs/PROMPT.md (1)

1-11: LGTM!

The eval prompt is clear and actionable with well-structured steps. The missing top-level heading flagged by markdownlint is appropriate here—this is an agent task description, not documentation requiring formal structure.

apps/example/playwright.config.ts (1)

7-27: LGTM!

The PORTLESS_HTTP_PORT constant and explicit env overrides ensure consistent configuration between Playwright and the dev scripts. Spreading process.env preserves the existing environment while overriding the specific portless settings.

apps/example/src/routes/index.tsx (1)

1-7: LGTM!

The redirect pattern using throw redirect({ to: "/docs" }) in beforeLoad follows TanStack Router's documented approach for route-level redirects. Clean and minimal.

docs/reference/remark.mdx (1)

1-109: LGTM!

Comprehensive documentation of the remark plugin stack. The Mermaid diagram clearly illustrates the processing order, and the code examples demonstrate both basic usage and advanced patterns like plugin replacement with options.

packages/leadtype/scripts/generate-docs.ts (1)

1-55: LGTM!

Clean migration from the llms.txt flow to AGENTS.md. The script properly:

  • Cleans up legacy artifacts (llms.txt, llms-full.txt)
  • Validates navigation groups with fail-fast behavior
  • Emits AGENTS.md at the package root for agent discovery

The validation step at lines 31-42 is a good safety net that catches config typos before they ship.

evals/evals/wire-content-negotiation/EVAL.ts (1)

6-11: The projectRoot resolution is correct. TRANSCRIPT_PATH is set to <tempDir>/__transcript__/transcript.json, and resolve(dirname(process.env.TRANSCRIPT_PATH), "..") correctly resolves to <tempDir> (the project root), which matches the comment's description.

docs/index.mdx (1)

13-67: Landing page restructuring is coherent and well-scoped.

The new “choose your path” + “what you get” flow reads clearly and matches the bundle/site split introduced in this PR.

evals/evals/bundle-own-docs/EVAL.ts (1)

17-63: Good coverage for the bundle workflow transcript checks.

These assertions directly validate the AGENTS.md discovery path, bundle guide read, and npm pack --dry-run behavior end-to-end.

apps/example/package.json (1)

7-9: Script and dependency updates look consistent with the docs pipeline changes.

The pre-convert step before dev/build and the Mermaid package addition align with the new docs rendering flow.

Also applies to: 34-45

evals/evals/validate-in-ci/EVAL.ts (1)

15-54: CI fixture assertions are well targeted.

This validates both discovery (AGENTS.md/docs reads) and concrete workflow output (lint-docs.yml flags), which is the right contract for this eval.

evals/lib/transcript.ts (1)

29-56: Transcript helper API is clean and cohesive.

transcriptPathFor, writeTranscript, and readTranscript are straightforward and match the harness/test integration points.

evals/lib/tools.test.ts (1)

18-100: Great baseline coverage for scoped path safety.

The escape-path rejection cases plus transcript assertions give strong confidence in the tool sandbox boundaries.

apps/example/src/routeTree.gen.ts (1)

1-9: Auto-generated file - no review needed.

This file is auto-generated by TanStack Router as indicated by the header comments. The changes correctly reflect the new route structure (/docs/quickstart, /docs/how-it-works, /docs/reference/*, /docs/build/*, /docs/authoring/*).

apps/example/vite.config.ts (3)

23-28: LGTM! Precompiled regex patterns at module level.

Good practice extracting these patterns as top-level constants—avoids recreating them on each request. As per coding guidelines: "Use top-level regex literals instead of creating them in loops."


30-58: LGTM! Clean URL rewriting logic.

The function correctly handles edge cases: missing accept header, already-.md URLs, non-docs paths, and browser requests that include text/html. The query string preservation on line 55-57 is a nice touch.


81-114: LGTM! Middleware plugin follows Vite patterns.

The plugin correctly hooks both configureServer and configurePreviewServer, and the middleware properly calls next() in all paths. The external tools context confirms this matches Vite's documented configureServer hook pattern.

evals/lib/sandbox.ts (2)

11-25: LGTM! Clear tarball discovery with helpful error messages.

The function provides actionable guidance when the tarball is missing, directing users to run the prerequisite command.


74-97: LGTM! Well-isolated npm subprocess.

Setting HOME: tempDir prevents npm from polluting the user's cache, and NPM_CONFIG_LOGLEVEL: "error" reduces noise. The error message correctly includes both exit code and stderr.

packages/leadtype/src/llm/llm.ts (2)

826-843: LGTM! Well-defined configuration types.

The AgentsMdConfig type clearly documents each field with JSDoc comments, and the optional docsSubdir with a sensible default provides flexibility without complexity.


864-948: LGTM! Clean AGENTS.md generation with proper edge case handling.

The function correctly:

  • Skips bestStartingPoints entries that don't exist in source docs (lines 897-901) rather than emitting broken links
  • Documents why agentGuidance is intentionally omitted (lines 938-941)
  • Uses consistent relative path format (./docs/<path>.md)

Based on learnings: "Ship agent-readable docs inside npm packages so IDEs and coding agents can read documentation offline."

docs/reference/llm.mdx (2)

1-5: LGTM! Proper frontmatter with group assignment.

The page correctly declares group: reference which will place it in the reference section of the navigation.


104-129: LGTM! Clear API documentation with practical options table.

The generateAgentsMd section clearly explains the difference from generateLlmsTxt (relative paths vs absolute URLs), and line 125 correctly notes that agentGuidance is intentionally ignored for offline agents.

packages/leadtype/src/cli/generate.ts (2)

59-76: LGTM! Well-structured discriminated result type.

The mode: "site" | "bundle" field combined with optional file paths creates a clear discriminated union pattern. Consumers can check mode to know which files properties will be populated.


392-448: LGTM! Clean branching between site and bundle modes.

The implementation correctly:

  • Runs convertAllMdx in both modes (line 385-390)
  • Generates AGENTS.md only in bundle mode
  • Skips llms.txt, llms-full, and search artifacts in bundle mode
  • Populates mode-appropriate result fields
evals/lib/tools.ts (3)

17-29: LGTM! Solid path sandboxing implementation.

The function correctly:

  • Strips leading slashes so absolute-looking paths become relative (line 21)
  • Uses path.resolve to normalize traversal attempts like ../..
  • Validates the resolved path starts with root + path.sep to prevent escapes

The check on line 25 (resolved !== root && !resolved.startsWith(root + path.sep)) properly handles both exact root matches and subdirectories.


140-185: LGTM! Read and write tools properly sandboxed.

Both tools:

  • Use resolveScoped to validate paths
  • Record operations to transcript with timing
  • The write tool correctly creates parent directories and tracks modified files

277-340: LGTM! npm tool has appropriate restrictions.

The implementation correctly:

  • Allowlists only pack and install subcommands (line 297)
  • Requires all args to start with - (flag-form only) to prevent arbitrary file/package injection (lines 300-305)
  • Isolates npm with restricted env (PATH, HOME, NPM_CONFIG_LOGLEVEL)

This prevents agents from running dangerous commands like npm publish or installing arbitrary packages by name.

apps/example/src/styles.css (2)

253-287: LGTM! Clean CSS-only step numbering with visual connectors.

The implementation uses:

  • CSS counters for automatic numbering (lines 254, 259, 264)
  • Pseudo-elements for the numbered circle and vertical connector line
  • Proper spacing with pb-8 and pl-12 for the step layout
  • :last-child handling to avoid trailing connector (line 268)

This is a solid approach that keeps the markup simple while achieving the connected-steps visual.


421-433: LGTM! Mermaid container styling updates.

The nested selector targeting [data-streamdown="mermaid-block"] removes conflicting styles from the Streamdown wrapper, allowing the mermaid diagram to render cleanly.

Comment thread apps/example/src/components/site-header.tsx
Comment on lines +65 to +79
function forceUtf8OnTextResponses(res: Res) {
const original = res.setHeader.bind(res);
res.setHeader = (name, value) => {
if (
typeof name === "string" &&
name.toLowerCase() === "content-type" &&
typeof value === "string" &&
TEXT_CONTENT_TYPE_PATTERN.test(value) &&
!CHARSET_PATTERN.test(value)
) {
return original(name, `${value}; charset=utf-8`);
}
return original(name, value);
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Potential issue: original setHeader binding may not preserve all overloads.

The monkeypatch approach works but res.setHeader in Node's HTTP API can accept arrays and has specific return type expectations. The current implementation handles the common case but consider whether the original function's this context is correctly preserved for all call patterns.

That said, .bind(res) on line 66 should handle this correctly, and the patched function delegates to original for non-matching cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/example/vite.config.ts` around lines 65 - 79, The monkeypatch in
forceUtf8OnTextResponses currently binds res.setHeader to original and assumes
string arguments; update the patch to preserve all overloads and this context by
capturing the original as done (original = res.setHeader.bind(res)) but
implement the wrapper using a rest-args signature (e.g., (...args)) and call the
original via Reflect.apply(original, res, args) so return value and this are
preserved; additionally, handle non-string/array header values safely by
checking types before modifying value (only modify when name is a string equal
to "content-type" and value is a string matching TEXT_CONTENT_TYPE_PATTERN
without CHARSET_PATTERN), otherwise delegate to original unchanged.

Comment thread biome.jsonc Outdated
npm run build
```

Run lint first so missing or malformed frontmatter fails before the converter writes anything. Use `--format github` in CI to get inline annotations on the PR. Use `--json` on `generate` so automation can read the resolved groups and search index stats.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Capitalize product name in prose at Line 184.

Keep the CLI flag as --format github, but in surrounding text use “GitHub” (capital H) for the platform name.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~184-~184: The official name of this software platform is spelled with a capital “H”.
Context: ...fore the converter writes anything. Use --format github in CI to get inline annotations on the...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/build/connect-docs-site.mdx` at line 184, Update the prose around the
CLI flag so the platform name is correctly capitalized: keep the flag text
exactly as `--format github` but change the surrounding plain-text reference to
the platform to “GitHub” (capital H) in the sentence that currently reads "Use
`--format github` in CI to get inline annotations on the PR."

Comment thread docs/how-it-works.mdx Outdated
Comment thread evals/run-eval.ts Outdated
Comment thread evals/run-eval.ts
Comment on lines +39 to +45
Full docs at [docs.example.com](https://docs.example.com/docs). Highlights:

- `docs/llms.txt`
- `docs/components.md`
- `docs/convert.md`
- `docs/remark.md`
- `docs/llm.md`
- `docs/search.md`
- `docs/lint.md`
- [Quickstart](https://docs.example.com/docs/quickstart) — five-minute happy path.
- [How it works](https://docs.example.com/docs/how-it-works) — the mental model.
- [Build a docs site](https://docs.example.com/docs/build/connect-docs-site) — wire into your build.
- [Bundle docs into a package](https://docs.example.com/docs/build/bundle-package-docs) — ship docs inside an npm tarball.
- [CLI reference](https://docs.example.com/docs/reference/cli) — every flag.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
for p in quickstart how-it-works build/connect-docs-site build/bundle-package-docs reference/cli; do
  url="https://docs.example.com/docs/$p"
  code=$(curl -s -o /dev/null -w "%{http_code}" "$url" || true)
  echo "$code  $url"
done

Repository: inthhq/leadtype

Length of output: 322


🏁 Script executed:

cat packages/leadtype/README.md | head -50

Repository: inthhq/leadtype

Length of output: 1949


🏁 Script executed:

grep -r "docs.example.com" packages/leadtype/

Repository: inthhq/leadtype

Length of output: 3022


🏁 Script executed:

grep -r "https://" packages/leadtype/README.md | head -20

Repository: inthhq/leadtype

Length of output: 1112


🏁 Script executed:

fd -e md packages/leadtype/ -exec grep -l "docs\|documentation" {} \;

Repository: inthhq/leadtype

Length of output: 314


🏁 Script executed:

cat packages/leadtype/package.json | jq '.homepage, .repository, .bugs' 2>/dev/null || cat packages/leadtype/package.json | grep -E "homepage|repository|bugs|url" | head -10

Repository: inthhq/leadtype

Length of output: 74


🏁 Script executed:

find packages/leadtype -type d -name "docs" -o -name "doc" 2>/dev/null

Repository: inthhq/leadtype

Length of output: 41


🏁 Script executed:

grep -r "github.com\|leadtype" packages/leadtype/package.json | head -5

Repository: inthhq/leadtype

Length of output: 81


🏁 Script executed:

cat packages/leadtype/package.json

Repository: inthhq/leadtype

Length of output: 3638


🌐 Web query:

leadtype documentation site npm package

💡 Result:

No npm package named "leadtype" exists based on searches across npm registry, GitHub, and general web. The closest match is "leadconduit-types", a Node.js module for parsing lead data by type (e.g., phone, email, street) used in LeadConduit by ActiveProspect. Its documentation is on the npm page, GitHub repo (https://github.com/activeprospect/leadconduit-types#readme), and LeadConduit API docs (https://activeprospect.redoc.ly/docs/leadconduit/api/tag/Types/), listing supported types like phone, email, url, ssn, state, etc., with parsing examples such as types.phone.parse('(512) 789-1111'). Latest version 4.23.2 published Nov 2024, 935 weekly downloads.[1][2][3] Other lead-related packages include @leadcms/sdk (LeadCMS SDK/CLI),[4] @leadpipe/client (Leadpipe intent APIs client).[5] No dedicated documentation site for a "leadtype" package was found; queries returned lead management docs from unrelated services like Serviceform, EASI'R, LeadExec.[6][7][8]

Citations:


🏁 Script executed:

grep -r "homepage\|docs" . --include="*.json" --include="*.md" --exclude-dir=node_modules --exclude-dir=dist | grep -v "example.com" | grep -v ".test." | head -10

Repository: inthhq/leadtype

Length of output: 1206


🏁 Script executed:

cat packages/leadtype/scripts/generate-docs.ts 2>/dev/null || echo "Script not found or unreadable"

Repository: inthhq/leadtype

Length of output: 2220


🏁 Script executed:

cat README.md 2>/dev/null | head -30

Repository: inthhq/leadtype

Length of output: 1429


🏁 Script executed:

ls -la | head -20

Repository: inthhq/leadtype

Length of output: 1211


🏁 Script executed:

find . -maxdepth 2 -name "*.config.*" -o -name ".github" -type d | head -10

Repository: inthhq/leadtype

Length of output: 91


🏁 Script executed:

cat docs/docs.config.ts

Repository: inthhq/leadtype

Length of output: 1718


🏁 Script executed:

cat .github/workflows/*.yml 2>/dev/null | grep -E "deploy|docs|url" | head -20

Repository: inthhq/leadtype

Length of output: 130


🏁 Script executed:

find .github -type f -name "*.yml" -o -name "*.yaml" | xargs ls -la

Repository: inthhq/leadtype

Length of output: 215


Replace placeholder docs URLs before package publication.

The README links point to https://docs.example.com/docs/..., which is inaccessible (HTTP connection fails). These placeholders must be replaced with the actual production docs URL before the package is published, or users will encounter broken links. Update the 5 doc links (lines 39–45) and the example command (line 13) with the real docs domain once it's deployed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/leadtype/README.md` around lines 39 - 45, Replace the placeholder
docs domain "https://docs.example.com" used across the README: update the five
links in the docs list (the Quickstart, How it works, Build a docs site, Bundle
docs into a package, and CLI reference) and also update the example command that
references the example docs URL (the example command on line 13) to the real
production docs domain once it's available; search for the string
"docs.example.com" in the README and substitute the canonical production docs
hostname so all links point to the live documentation.

Comment thread packages/leadtype/src/cli.test.ts
Comment thread README.md
Comment on lines +30 to +63
- **[Build a docs site](https://docs.example.com/docs/build/connect-docs-site)** — wire leadtype into your build to convert MDX, index search, and serve markdown to agents.
- **[Bundle docs into your package](https://docs.example.com/docs/build/bundle-package-docs)** — ship `AGENTS.md` plus topic markdown inside the npm tarball so coding agents auto-discover them from `node_modules/<your-package>/AGENTS.md`.

## Install

```bash
pnpm add leadtype
```

## Basic Usage

### Own MDX components in your app

`leadtype` does not export prebuilt React, Vue, Nuxt, Svelte, or Astro components. Define the MDX component map in the docs app that renders your pages.

## Live Example App
## 30-second example

The repo includes a canonical consumer demo at `apps/example`.

- Renders real `.mdx` fixture files through app-owned `mdxComponents`.
- Uses TanStack Start for SSR and hydration coverage.
- Shows extracted `ExtractedTypeTable` output while keeping pipeline fixtures in the validation path.

Local workflow:
For a hosted docs site:

```bash
bun install
bun run dev
npx leadtype generate --src . --out public --base-url https://docs.example.com
```

Pipeline and browser checks:
For an npm-bundled doc set:

```bash
bun run --filter example pipeline:build
bun run --filter example pipeline:test
bun run --filter example test:e2e
npx leadtype generate --bundle --src . --out packages/my-package
```

Validation layers:

- Package unit tests in `packages/leadtype/src/**/*.test.ts*` cover framework-neutral conversion, search, linting, and generated docs behavior.
- Pipeline fixtures in `apps/example/scripts` and `apps/example/content` cover MDX conversion, LLM generation, and `ExtractedTypeTable`.
- The TanStack Start demo app in `apps/example/src` covers real browser rendering and hydration.

## Where This Fits
The first produces `public/llms.txt`, `public/docs/llms-full/*.txt`, `public/docs/search-index.json`, and `public/docs/*.md`. The second produces `packages/my-package/AGENTS.md` and `packages/my-package/docs/*.md` — auto-discoverable by [25+ coding agents](https://agents.md) once the package is installed.

`leadtype` is not a hosted docs platform or a complete docs-site framework. Use tools such as Mintlify, Fumadocs, or Starlight when the primary job is shipping a polished docs website quickly.
## Documentation

Use this package when the primary job is shared docs infrastructure: MDX-to-markdown conversion, LLM bundles, linting, static search artifacts, answer helpers, and agent-facing docs output that can feed multiple apps and tools.
Full docs at [docs.example.com](https://docs.example.com/docs):

The pipeline entry points are framework-neutral. React, Vue, Nuxt, Svelte, Astro, and other stacks can use conversion, LLM, lint, and search APIs while owning their own runtime component rendering.
- [Quickstart](https://docs.example.com/docs/quickstart)
- [How it works](https://docs.example.com/docs/how-it-works)
- [Frontmatter](https://docs.example.com/docs/authoring/frontmatter)
- [CLI reference](https://docs.example.com/docs/reference/cli)
- [Methodology](https://docs.example.com/docs/methodology) — how leadtype differs from Fumadocs, Starlight, and Mintlify
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace placeholder docs host in user-facing links

Lines 30-63 use https://docs.example.com/... as primary documentation links. If that host isn’t live for this project, users will hit dead links from the README.

Use the real docs origin (or repository-relative links) before merge so the README remains navigable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 30 - 63, Replace the placeholder docs host
"https://docs.example.com" used across the README (including the 30-second
example commands and links to Quickstart, How it works, Frontmatter, CLI
reference, Methodology, and the two example outputs like AGENTS.md/llms.txt)
with the real documentation origin or repository-relative paths; update the npx
generate examples to use the real --base-url or remove the host so they work
locally, and ensure all user-facing links point to live docs or relative URLs
before merging.

- site-header markdownHrefForPath: normalize trailing slash before checking
  the /docs root so /docs/ resolves to /docs/index.md instead of /docs.md.
- biome.jsonc: refresh stale @vercel/agent-eval comment to reflect the
  custom AI SDK harness that replaced it.
- how-it-works "What runs when": rewrite the step list to be mode-agnostic.
  Site mode emits llms.txt + llms-full + search index; --bundle emits
  AGENTS.md instead. Output dir is conditional on mode, not hardcoded to
  public/docs/.
- 4 EVAL.ts files: replace `c.args.path as string ?? ""` with a runtime
  typeof guard in the filter so reads only contains real strings.
- wire-content-negotiation/EVAL.ts: extract getViteConfigSource helper to
  DRY up two tests that read vite.config.ts the same way.
- evals/lib/sandbox.ts: wrap the cp call in try/catch so failures include
  fixtureDir → tempDir context with the original error as cause.
- evals/run-eval.ts (three sub-fixes):
  - --runs validates positive integer (extracted parsePositiveInt helper);
    --runs 0 / --runs notanumber now error clearly instead of producing
    NaN summary math.
  - runVitest gains a settle-once guard, an error listener on the spawn,
    and a try/catch around spawn() so the promise can't hang on launch
    failure.
  - sandbox.cleanup() moved into a finally block so the tempdir is removed
    even if runVitest or archiveTranscript throws.
- cli.test.ts bundle-mode test: also assert search-content.json is absent
  alongside the existing search-index.json check.

Skipped 5 review findings with reasons (see plan file): vite.config.ts
setHeader patch (already correct — bind preserves this, return value
preserved, types narrowed before mutation), connect-docs-site.mdx "github"
capitalization (no plain-text reference exists; only the literal flag
value), PROMPT.md MD041 H1 headings (markdownlint not enforced; would
mutate agent input for no benefit), and two README docs.example.com
placeholders (no production domain registered yet).

Verified: 98/98 leadtype tests pass, 9/9 eval unit tests pass, ultracite
clean, typecheck clean.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@evals/run-eval.ts`:
- Around line 260-280: Replace the dynamic import of node:fs/promises inside
archiveTranscript with top-level named imports for mkdir and writeFile (add
mkdir and writeFile to the existing readFile import), remove the await
import(...) and the local fs binding, and update calls from fs.mkdir(...) and
fs.writeFile(...) to direct mkdir(...) and writeFile(...); keep readFile(...)
usage as-is and ensure path.join(dir, "files", rel) and any mkdir calls still
use path.dirname(dest) where appropriate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c2235bd5-7a91-42c5-99aa-75a27b1955b3

📥 Commits

Reviewing files that changed from the base of the PR and between be8b4a6 and 86eec4e.

📒 Files selected for processing (10)
  • apps/example/src/components/site-header.tsx
  • biome.jsonc
  • docs/how-it-works.mdx
  • evals/evals/bundle-own-docs/EVAL.ts
  • evals/evals/explain-cli-flag/EVAL.ts
  • evals/evals/validate-in-ci/EVAL.ts
  • evals/evals/wire-content-negotiation/EVAL.ts
  • evals/lib/sandbox.ts
  • evals/run-eval.ts
  • packages/leadtype/src/cli.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • evals/evals/bundle-own-docs/EVAL.ts
  • evals/lib/sandbox.ts
  • evals/evals/wire-content-negotiation/EVAL.ts
  • evals/evals/explain-cli-flag/EVAL.ts
  • packages/leadtype/src/cli.test.ts
  • evals/evals/validate-in-ci/EVAL.ts
  • evals/run-eval.ts
  • apps/example/src/components/site-header.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • evals/evals/bundle-own-docs/EVAL.ts
  • evals/lib/sandbox.ts
  • evals/evals/wire-content-negotiation/EVAL.ts
  • evals/evals/explain-cli-flag/EVAL.ts
  • packages/leadtype/src/cli.test.ts
  • evals/evals/validate-in-ci/EVAL.ts
  • evals/run-eval.ts
  • apps/example/src/components/site-header.tsx
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/cli.test.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use the key prop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
Avoid dangerouslySetInnerHTML unless absolutely necessary
Use proper image components (e.g., Next.js <Image>) over <img> tags
Use Next.js <Image> component for images
Use next/head or App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead of React.forwardRef in React 19+

Files:

  • apps/example/src/components/site-header.tsx
**/*.{jsx,tsx,html}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Add rel="noopener" when using target="_blank" on links

Files:

  • apps/example/src/components/site-header.tsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Convert MDX into clean markdown that agents and tools can read
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Validate frontmatter, navigation, and internal links before publish using leadtype lint
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Ship agent-readable docs inside npm packages so IDEs and coding agents can read them offline
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Generate llms.txt and topic-scoped full-context bundles from a single MDX source for LLM consumption
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Wire leadtype into a docs site build to serve humans, agents, and search from one source
Learnt from: CR
Repo: inthhq/leadtype

Timestamp: 2026-05-09T16:51:58.518Z
Learning: Use a remark plugin stack to flatten MDX components into markdown during conversion
🪛 LanguageTool
docs/how-it-works.mdx

[uncategorized] ~33-~33: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...old headings, a <TypeTable> becomes a markdown table. The flattened markdown is what e...

(MARKDOWN_NNP)


[style] ~73-~73: Consider a different adjective to strengthen your wording.
Context: ...t over HTTP and follow absolute URLs to deeper context. Useless inside an npm tarball,...

(DEEP_PROFOUND)

🔍 Remote MCP Context7

Additional factual context for reviewing this PR

  • Vite plugin middleware lifecycle

    • configureServer receives the ViteDevServer and is used to add custom middleware via server.middlewares.use; returning a function from configureServer registers middleware that runs after Vite’s internal middlewares (so both pre- and post-injection patterns shown are supported). This validates the plugin pattern used for content-negotiation and header modification (append charset).
  • Vite middleware examples / guidance

    • Examples show using server.middlewares.use(...) to intercept/modify requests and responses in both dev and preview servers; configurePreviewServer exists for preview-specific middleware. This supports the PR’s adding middleware to dev + preview and manipulating response Content-Type.
  • TanStack Router not-found and file-route patterns

    • createFileRoute / createRootRoute file-based routing conventions and examples are documented; root-level notFoundComponent is recommended and createRouter supports defaultNotFoundComponent for a router-wide fallback. Using both a NotFound component on the root route and setting defaultNotFoundComponent on the router (as this PR does) matches documented patterns for providing consistent 404 handling. Also, createFileRoute examples show how to throw notFound() from loaders and supply per-route notFoundComponent.
  • Vercel AI SDK tool helper and Zod schemas

    • The recommended pattern for defining callable tools is tool({ description, inputSchema: z.object(...), execute: async (...) => ... }), which performs input validation and provides a typed execute. The PR’s scoped tools using tool() + zod input schemas and execute functions align with examples in the SDK docs.

Sources consulted (Context7 MCP):

  • Vite plugin/middleware docs and examples — Context7 query on Vite configureServer and plugin hooks.
  • TanStack Router file-route and not-found handling docs.
  • Vercel AI SDK tool() + Zod tool-calling examples.
🔇 Additional comments (16)
docs/how-it-works.mdx (1)

146-150: Execution-order section is now mode-accurate and clear.

This now correctly distinguishes default site outputs from --bundle outputs and removes the earlier ambiguity.

biome.jsonc (1)

39-54: Scoped Biome override is appropriate for eval fixtures and harness tests.

The rationale and rule exemptions are aligned with the new custom eval harness and are correctly limited to evals/**.

packages/leadtype/src/cli.test.ts (3)

118-119: Build-path and group-slug migration checks look correct.

These assertions correctly enforce the docs/build/* output and "build" group slug contract.

Also applies to: 172-172


188-205: Include/exclude glob behavior is validated cleanly for the new IA.

The updated glob expectations and emitted/omitted file assertions are coherent and precise.

Also applies to: 221-234


346-398: --bundle coverage is strong and aligns with the new artifact contract.

Great test scope here: mode verification, AGENTS.md emission, relative-link sanity, omission of llms/search artifacts (including search-content.json), and retained markdown outputs.

apps/example/src/components/site-header.tsx (3)

8-30: RobotIcon implementation looks good.

Clean SVG component, and aria-hidden="true" avoids redundant screen-reader noise for the decorative icon.


34-47: markdownHrefForPath normalization logic is correct.

The trailing-slash normalization and /docs/docs/index.md mapping now handle the docs root and nested routes safely.


67-79: External markdown link is safely and conditionally rendered.

Good use of target="_blank" with rel="noopener", and rendering only when a valid markdown href is available.

evals/evals/explain-cli-flag/EVAL.ts (1)

11-13: Type narrowing addressed, residual assertion is safe.

The previous review about type narrowing has been addressed: the filter now includes typeof c.args.path === "string". The as string on line 13 is technically redundant since TypeScript's control flow doesn't narrow across filtermap boundaries, but it's safe given the runtime check. No action needed.

evals/evals/wire-content-negotiation/EVAL.ts (1)

17-23: Helper extraction addresses previous feedback.

The getViteConfigSource() helper properly consolidates the duplicated file-reading logic from the previous review. Good refactor.

evals/run-eval.ts (3)

35-41: Previous feedback on --runs validation has been addressed.

The parsePositiveInt helper correctly validates that --runs is a positive integer and throws a clear error message for invalid values.

Also applies to: 62-63


196-243: Sandbox cleanup now in finally block — previous feedback addressed.

The sandbox.cleanup() call is correctly placed in a finally block (line 241-243), ensuring temp directories are cleaned up even if runVitest or archiveTranscript throws.


288-331: Spawn error handling properly implemented.

The runVitest function now handles spawn errors correctly:

  • Uses a settled flag to prevent multiple resolves
  • Wraps spawn in try-catch for synchronous failures
  • Attaches an error event listener for async spawn failures

This addresses the previous review feedback.

evals/lib/sandbox.ts (1)

1-105: LGTM!

The sandbox implementation is well-structured with proper error handling. The cp operation is now wrapped in try-catch with a clear diagnostic message (addressing the past review comment), and npmInstall correctly captures stderr and surfaces failures with exit codes.

evals/evals/bundle-own-docs/EVAL.ts (1)

1-63: LGTM!

The test suite properly validates the agent's bundle-own-docs behavior: checking AGENTS.md discovery, package.json configuration with --bundle in prepack, and npm pack verification. The type checking patterns are consistent with other eval files.

evals/evals/validate-in-ci/EVAL.ts (1)

1-54: LGTM!

The test suite validates the CI workflow generation comprehensively: checking AGENTS.md discovery, documentation reads, workflow file creation, and correct flags usage. Pattern is consistent with other eval files.

Comment thread evals/run-eval.ts
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