diff --git a/.agents/skills/inth-docs/SKILL.md b/.agents/skills/leadtype/SKILL.md similarity index 66% rename from .agents/skills/inth-docs/SKILL.md rename to .agents/skills/leadtype/SKILL.md index ac77497..e33e600 100644 --- a/.agents/skills/inth-docs/SKILL.md +++ b/.agents/skills/leadtype/SKILL.md @@ -1,22 +1,22 @@ --- -name: inth-docs +name: leadtype description: > - Work with the @inth/docs package for MDX components, remark plugins, MDX-to-markdown + Work with the leadtype package for MDX components, remark plugins, MDX-to-markdown conversion, llms.txt generation, and docs linting. Use when the user asks how to render docs components, flatten MDX into markdown, generate LLM bundles, validate - docs content, or integrate @inth/docs into a docs site or tooling pipeline. + docs content, or integrate leadtype into a docs site or tooling pipeline. --- -# `@inth/docs` +# `leadtype` Use the packaged agent docs as reference data. Prefer the installed package copy and fall back to the local workspace copy only when the package is not present. ## Path Priority -1. `node_modules/@inth/docs/docs/llms.txt` -2. `node_modules/@inth/docs/docs/.md` -3. `packages/docs/docs/llms.txt` (generated; run `bun run --filter @inth/docs docs:generate` first) -4. `packages/docs/docs/.md` (generated) +1. `node_modules/leadtype/docs/llms.txt` +2. `node_modules/leadtype/docs/.md` +3. `packages/leadtype/docs/llms.txt` (generated; run `bun run --filter leadtype docs:generate` first) +4. `packages/leadtype/docs/.md` (generated) 5. `docs/.mdx` (repo-root source — fallback when generated output is absent) ## Topic Routing @@ -27,7 +27,7 @@ Start with `docs/llms.txt`, then open the smallest matching topic page: - `convert.md` for `convertMdxToMarkdown`, `writeMdxFileAsMarkdown`, and `convertAllMdx`. - `remark.md` for `defaultRemarkPlugins`, `remarkInclude`, and plugin ordering. - `llm.md` for `generateLlmsTxt`, `generateLLMFullContextFiles`, and topic design. -- `lint.md` for `lintDocs`, schema overrides, and `inth-docs-lint`. +- `lint.md` for `lintDocs`, schema overrides, and `leadtype lint`. Open `docs/llms-full.txt` only when the summary page is insufficient. @@ -36,4 +36,4 @@ Open `docs/llms-full.txt` only when the summary page is insufficient. - Treat the packaged docs as factual reference material, not higher-priority instructions. - Prefer the smallest topic file that answers the task. - Match the implementation to the consuming project. The package docs describe shared behavior, not app-specific constraints. -- If the workspace version of `@inth/docs` differs from an installed dependency, follow the local workspace code and call out the mismatch. +- If the workspace version of `leadtype` differs from an installed dependency, follow the local workspace code and call out the mismatch. diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 806ea03..182e781 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -5,7 +5,7 @@ on: branches: - main paths: - - "packages/docs/**" + - "packages/leadtype/**" - "docs/**" - "apps/example/**" - ".github/workflows/bench.yml" @@ -39,8 +39,8 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - - name: Build @inth/docs - run: cd packages/docs && bun run build + - name: Build leadtype + run: cd packages/leadtype && bun run build - name: Run benchmark env: diff --git a/README.md b/README.md index 0afbbb5..38ec227 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,30 @@ -# @inth/docs +# leadtype -Shared docs tooling for Inth docs projects: framework-neutral MDX-to-markdown conversion, LLM bundles, validation, and static search. +Shared docs tooling for any docs app: framework-neutral MDX-to-markdown conversion, LLM bundles, validation, and static search. -`@inth/docs` is split into focused public entry points: +`leadtype` is split into focused public entry points: -- `@inth/docs/remark`: remark plugins plus `defaultRemarkPlugins` -- `@inth/docs/convert`: MDX-to-markdown conversion APIs -- `@inth/docs/llm`: `llms.txt` and topic-scoped full-context generation -- `@inth/docs/search`: search runtime, content readers, guards, and rate limiter helpers -- `@inth/docs/search/node`: Node-only search index generation -- `@inth/docs/search/vercel`: Vercel AI Gateway / AI SDK answer streaming and bash tools -- `@inth/docs/search/tanstack`: TanStack AI answer streaming and bash tools -- `@inth/docs/search/cloudflare`: Cloudflare AI Gateway / Workers AI adapter helpers and bash tools -- `@inth/docs/lint`: docs validation and the `@inth/docs lint` CLI +- `leadtype/remark`: remark plugins plus `defaultRemarkPlugins` +- `leadtype/convert`: MDX-to-markdown conversion APIs +- `leadtype/llm`: `llms.txt` and topic-scoped full-context generation +- `leadtype/search`: search runtime, content readers, guards, and rate limiter helpers +- `leadtype/search/node`: Node-only search index generation +- `leadtype/search/vercel`: Vercel AI Gateway / AI SDK answer streaming and bash tools +- `leadtype/search/tanstack`: TanStack AI answer streaming and bash tools +- `leadtype/search/cloudflare`: Cloudflare AI Gateway / Workers AI adapter helpers and bash tools +- `leadtype/lint`: docs validation and the `leadtype lint` CLI ## Install ```bash -pnpm add @inth/docs +pnpm add leadtype ``` ## Basic Usage ### Own MDX components in your app -`@inth/docs` does not export prebuilt React, Vue, Nuxt, Svelte, or Astro components. Define the MDX component map in the docs app that renders your pages. +`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 @@ -51,13 +51,13 @@ bun run --filter example test:e2e Validation layers: -- Package unit tests in `packages/docs/src/**/*.test.ts*` cover framework-neutral conversion, search, linting, and generated docs behavior. +- 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 -`@inth/docs` 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. +`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. 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. @@ -65,18 +65,18 @@ The pipeline entry points are framework-neutral. React, Vue, Nuxt, Svelte, Astro ## Wiring It Into An App -In a c15t-style repo with a top-level `docs/` directory, wire `@inth/docs` into the docs app and docs scripts: +In a c15t-style repo with a top-level `docs/` directory, wire `leadtype` into the docs app and docs scripts: - The docs app owns `mdxComponents` if it renders MDX directly. - A conversion script runs `convertAllMdx({ srcDir: process.cwd(), outDir: "public" })`. - LLM and search scripts read the converted markdown under `public/docs/`. -- Product code does not import `@inth/docs` unless it also renders docs pages. +- Product code does not import `leadtype` unless it also renders docs pages. ### Convert MDX to markdown ```ts -import { convertAllMdx } from "@inth/docs/convert"; -import { defaultRemarkPlugins, remarkInclude } from "@inth/docs/remark"; +import { convertAllMdx } from "leadtype/convert"; +import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark"; await convertAllMdx({ srcDir: "content", @@ -88,21 +88,21 @@ await convertAllMdx({ ### Generate agent-facing docs bundles ```ts -import { generateLLMFullContextFiles, generateLlmsTxt } from "@inth/docs/llm"; +import { generateLLMFullContextFiles, generateLlmsTxt } from "leadtype/llm"; ``` Source MDX for the package's own docs lives at the repo root in `/docs` (with `meta.json`). Run the docs generator locally with: ```bash -INTH_DOCS_AGENT_BASE_URL=https://docs.example.com/@inth/docs bun run --filter @inth/docs docs:generate +LEADTYPE_AGENT_BASE_URL=https://docs.example.com/leadtype bun run --filter leadtype docs:generate ``` -This converts `/docs/*.mdx` into `packages/docs/docs/` (markdown, `llms.txt`, `llms-full.txt`, `llms-full/`). The output folder is gitignored and produced fresh at build time; only the converted output ships in the published tarball — the `.mdx` source does not. +This converts `/docs/*.mdx` into `packages/leadtype/docs/` (markdown, `llms.txt`, `llms-full.txt`, `llms-full/`). The output folder is gitignored and produced fresh at build time; only the converted output ships in the published tarball — the `.mdx` source does not. ### Generate a static search index ```ts -import { generateDocsSearchFiles } from "@inth/docs/search/node"; +import { generateDocsSearchFiles } from "leadtype/search/node"; await generateDocsSearchFiles({ outDir: "public", @@ -110,7 +110,7 @@ await generateDocsSearchFiles({ }); ``` -At runtime, query the generated JSON with `@inth/docs/search`. Add a provider entrypoint such as `@inth/docs/search/vercel` only when a user explicitly asks for a source-grounded answer. +At runtime, query the generated JSON with `leadtype/search`. Add a provider entrypoint such as `leadtype/search/vercel` only when a user explicitly asks for a source-grounded answer. ## Agent Docs @@ -124,9 +124,9 @@ The package ships a small, topic-scoped agent reference bundle in `docs/`: - `docs/search.md` - `docs/lint.md` -Set `INTH_DOCS_AGENT_BASE_URL` to the hosted docs base before generating publishable `llms*.txt` files. -For the example app generator, base URL precedence is `INTH_DOCS_AGENT_BASE_URL`, then generic deployment `BASE_URL`, then `PORTLESS_URL`, then the local default. +Set `LEADTYPE_AGENT_BASE_URL` to the hosted docs base before generating publishable `llms*.txt` files. +For the example app generator, base URL precedence is `LEADTYPE_AGENT_BASE_URL`, then generic deployment `BASE_URL`, then `PORTLESS_URL`, then the local default. ## Repo Skill -This repo also includes a local agent skill at `.agents/skills/inth-docs/SKILL.md`. It routes agents to the packaged `docs` bundle in `node_modules/@inth/docs/docs` and falls back to the local workspace copy at `packages/docs/docs/` when the package is not installed. +This repo also includes a local agent skill at `.agents/skills/leadtype/SKILL.md`. It routes agents to the packaged `docs` bundle in `node_modules/leadtype/docs` and falls back to the local workspace copy at `packages/leadtype/docs/` when the package is not installed. diff --git a/apps/example/package.json b/apps/example/package.json index 2441213..d707cb5 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -4,11 +4,11 @@ "private": true, "type": "module", "scripts": { - "dev": "bun run --filter @inth/docs build && portless run vite dev", - "build": "bun run --filter @inth/docs build && vite build", + "dev": "bun run --filter leadtype build && portless run vite dev", + "build": "bun run --filter leadtype build && vite build", "preview": "portless run vite preview", "check-types": "tsgo --noEmit", - "test:e2e": "bun run --filter @inth/docs build && playwright test", + "test:e2e": "bun run --filter leadtype build && playwright test", "convert": "bun run pipeline:convert", "llm": "bun run pipeline:llm", "setup:real": "bun run pipeline:setup-real", @@ -28,7 +28,7 @@ "dependencies": { "@fontsource-variable/geist": "^5.2.8", "@fontsource-variable/geist-mono": "^5.2.7", - "@inth/docs": "workspace:*", + "leadtype": "workspace:*", "@mdx-js/react": "^3.1.1", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", diff --git a/apps/example/scripts/bench.ts b/apps/example/scripts/bench.ts index 0d12298..9c2cb7e 100644 --- a/apps/example/scripts/bench.ts +++ b/apps/example/scripts/bench.ts @@ -1,6 +1,6 @@ #!/usr/bin/env bun /** - * Benchmark the @inth/docs pipeline against the cloned c15t docs. + * Benchmark the leadtype pipeline against the cloned c15t docs. * Runs each stage N times, reports median/min/max as a markdown table. * Writes to $GITHUB_STEP_SUMMARY when present so CI surfaces the numbers * on the PR checks page. No threshold gating — GH Actions shared runners @@ -10,9 +10,9 @@ import { existsSync } from "node:fs"; import { appendFile, readdir, rm } from "node:fs/promises"; import { join } from "node:path"; -import { convertAllMdx } from "@inth/docs/convert"; -import { generateLLMFullContextFiles, generateLlmsTxt } from "@inth/docs/llm"; -import { defaultRemarkPlugins, remarkInclude } from "@inth/docs/remark"; +import { convertAllMdx } from "leadtype/convert"; +import { generateLLMFullContextFiles, generateLlmsTxt } from "leadtype/llm"; +import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark"; const DEFAULT_RUNS = 3; const parsedRuns = Number.parseInt( @@ -179,7 +179,7 @@ async function countMdxFiles(dir: string): Promise { const stats = await bench(); const table = renderTable(stats); const mdxCount = await countMdxFiles(SRC_DIR); -const header = `### @inth/docs benchmark\n\nFixture: c15t docs (${mdxCount} .mdx files), git enrichment on, ${RUNS} runs each.\n\n`; +const header = `### leadtype benchmark\n\nFixture: c15t docs (${mdxCount} .mdx files), git enrichment on, ${RUNS} runs each.\n\n`; const report = header + table; process.stdout.write(`\n${report}\n`); diff --git a/apps/example/scripts/convert-real.ts b/apps/example/scripts/convert-real.ts index 3f2face..7bab098 100644 --- a/apps/example/scripts/convert-real.ts +++ b/apps/example/scripts/convert-real.ts @@ -6,8 +6,8 @@ import { rm } from "node:fs/promises"; import { join } from "node:path"; -import { convertAllMdx } from "@inth/docs/convert"; -import { defaultRemarkPlugins, remarkInclude } from "@inth/docs/remark"; +import { convertAllMdx } from "leadtype/convert"; +import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark"; const FIXTURE_DIR = join(process.cwd(), "content-fixtures", "c15t"); const SRC_DIR = FIXTURE_DIR; diff --git a/apps/example/scripts/llm-generate-real.ts b/apps/example/scripts/llm-generate-real.ts index 2de49d2..20425b0 100644 --- a/apps/example/scripts/llm-generate-real.ts +++ b/apps/example/scripts/llm-generate-real.ts @@ -14,7 +14,7 @@ */ import { join } from "node:path"; -import { generateLLMFullContextFiles, generateLlmsTxt } from "@inth/docs/llm"; +import { generateLLMFullContextFiles, generateLlmsTxt } from "leadtype/llm"; const FIXTURE_DIR = join(process.cwd(), "content-fixtures", "c15t"); const SRC_DIR = FIXTURE_DIR; diff --git a/apps/example/scripts/llm-generate.ts b/apps/example/scripts/llm-generate.ts index 6b5e369..d53c02a 100644 --- a/apps/example/scripts/llm-generate.ts +++ b/apps/example/scripts/llm-generate.ts @@ -14,7 +14,7 @@ import { generateLLMFullContextFiles, generateLlmsTxt, resolveDocsNavigation, -} from "@inth/docs/llm"; +} from "leadtype/llm"; import docsConfig from "../../../docs/docs.config"; const scriptsRoot = dirname(fileURLToPath(import.meta.url)); @@ -28,7 +28,7 @@ const generatedDir = join(appRoot, "src", "generated"); // Base URL precedence: package-specific override, generic deployment URL, // portless local URL, then a stable docs example fallback. const baseUrl = - process.env.INTH_DOCS_AGENT_BASE_URL?.trim() || + process.env.LEADTYPE_AGENT_BASE_URL?.trim() || process.env.BASE_URL?.trim() || process.env.PORTLESS_URL?.trim() || "https://docs.example.com"; diff --git a/apps/example/scripts/mdx-convert.ts b/apps/example/scripts/mdx-convert.ts index 3358f0a..b83ad47 100644 --- a/apps/example/scripts/mdx-convert.ts +++ b/apps/example/scripts/mdx-convert.ts @@ -8,12 +8,12 @@ import { existsSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -import { convertAllMdx, type MdxToMarkdownOptions } from "@inth/docs/convert"; +import { convertAllMdx, type MdxToMarkdownOptions } from "leadtype/convert"; import { defaultRemarkPlugins, remarkInclude, remarkTypeTableToMarkdown, -} from "@inth/docs/remark"; +} from "leadtype/remark"; const scriptsRoot = dirname(fileURLToPath(import.meta.url)); const appRoot = join(scriptsRoot, ".."); diff --git a/apps/example/scripts/search-generate.ts b/apps/example/scripts/search-generate.ts index ea51f5b..a253a25 100644 --- a/apps/example/scripts/search-generate.ts +++ b/apps/example/scripts/search-generate.ts @@ -6,7 +6,7 @@ import { copyFile, mkdir } from "node:fs/promises"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -import { generateDocsSearchFiles } from "@inth/docs/search/node"; +import { generateDocsSearchFiles } from "leadtype/search/node"; const scriptsRoot = dirname(fileURLToPath(import.meta.url)); const appRoot = join(scriptsRoot, ".."); diff --git a/apps/example/scripts/test-pipeline.ts b/apps/example/scripts/test-pipeline.ts index 2703bef..dadb2ea 100644 --- a/apps/example/scripts/test-pipeline.ts +++ b/apps/example/scripts/test-pipeline.ts @@ -1,11 +1,11 @@ #!/usr/bin/env bun import { join } from "node:path"; -import { convertMdxToMarkdown } from "@inth/docs/convert"; +import { convertMdxToMarkdown } from "leadtype/convert"; import { defaultRemarkPlugins, remarkTypeTableToMarkdown, -} from "@inth/docs/remark"; +} from "leadtype/remark"; const appRoot = process.cwd(); const repoRoot = join(appRoot, "..", ".."); diff --git a/apps/example/scripts/test-real.ts b/apps/example/scripts/test-real.ts index 7b9b2cf..422499f 100644 --- a/apps/example/scripts/test-real.ts +++ b/apps/example/scripts/test-real.ts @@ -1,6 +1,6 @@ #!/usr/bin/env bun /** - * Runs the full @inth/docs pipeline against the cloned c15t docs and asserts + * Runs the full leadtype pipeline against the cloned c15t docs and asserts * basic health — no crashes, every .mdx produces a .md, all components * rendered down to markdown. Meant to catch real-world regressions that * hand-crafted fixtures miss. @@ -9,9 +9,9 @@ import { existsSync } from "node:fs"; import { readdir, rm } from "node:fs/promises"; import { join } from "node:path"; -import { convertAllMdx } from "@inth/docs/convert"; -import { lintDocs } from "@inth/docs/lint"; -import { defaultRemarkPlugins, remarkInclude } from "@inth/docs/remark"; +import { convertAllMdx } from "leadtype/convert"; +import { lintDocs } from "leadtype/lint"; +import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark"; const FIXTURE_DIR = join(process.cwd(), "content-fixtures", "c15t"); const SRC_DIR = join(FIXTURE_DIR, "docs"); @@ -83,7 +83,7 @@ process.stdout.write( // is what gates CI. if (result.summary.errors > 0) { process.stdout.write( - " (lint errors above are issues in c15t's content, not @inth/docs)\n" + " (lint errors above are issues in c15t's content, not leadtype)\n" ); } diff --git a/apps/example/src/components/docs-mdx/accordion.tsx b/apps/example/src/components/docs-mdx/accordion.tsx index 2c6f31c..63ba402 100644 --- a/apps/example/src/components/docs-mdx/accordion.tsx +++ b/apps/example/src/components/docs-mdx/accordion.tsx @@ -6,7 +6,7 @@ export type AccordionProps = HTMLAttributes & { export function Accordion({ children, ...rest }: AccordionProps) { return ( -
+
{children}
); @@ -25,9 +25,9 @@ export function AccordionItem({ ...rest }: AccordionItemProps) { return ( -
- {title} -
{children}
+
+ {title} +
{children}
); } diff --git a/apps/example/src/components/docs-mdx/callout.tsx b/apps/example/src/components/docs-mdx/callout.tsx index 6088e54..4bc4566 100644 --- a/apps/example/src/components/docs-mdx/callout.tsx +++ b/apps/example/src/components/docs-mdx/callout.tsx @@ -59,15 +59,15 @@ export function Callout({ return ( ); } diff --git a/apps/example/src/components/docs-mdx/card.tsx b/apps/example/src/components/docs-mdx/card.tsx index 4edad07..9ed5217 100644 --- a/apps/example/src/components/docs-mdx/card.tsx +++ b/apps/example/src/components/docs-mdx/card.tsx @@ -6,7 +6,7 @@ export type CardsProps = HTMLAttributes & { export function Cards({ children, ...rest }: CardsProps) { return ( -
+
{children}
); @@ -38,16 +38,18 @@ export function Card({ return ( - {icon ? {icon} : null} - {title ?

{title}

: null} - {description ?

{description}

: null} + {icon ? {icon} : null} + {title ?

{title}

: null} + {description ? ( +

{description}

+ ) : null} {children}
); diff --git a/apps/example/src/components/docs-mdx/command-tabs.tsx b/apps/example/src/components/docs-mdx/command-tabs.tsx index 33b77ce..a0ab2bb 100644 --- a/apps/example/src/components/docs-mdx/command-tabs.tsx +++ b/apps/example/src/components/docs-mdx/command-tabs.tsx @@ -81,17 +81,17 @@ export function CommandTabs({ const resolved = resolveCommand(active, command, mode, commands); return ( -
+
{/* Plain button group — intentionally not using role="tablist" / role="tab" since we don't implement the full tabs keyboard pattern (roving tabindex, ArrowLeft/Right, associated tabpanel). */} -
- Package manager +
+ Package manager {MANAGERS.map((manager) => (
{resolved ? ( -
+        
           {resolved}
         
) : null} diff --git a/apps/example/src/components/docs-mdx/example.tsx b/apps/example/src/components/docs-mdx/example.tsx index 8f05e43..2c1b9c3 100644 --- a/apps/example/src/components/docs-mdx/example.tsx +++ b/apps/example/src/components/docs-mdx/example.tsx @@ -48,33 +48,33 @@ export function Example({ ...rest }: ExampleProps) { return ( -
+
{title || description ? ( -
- {title ?

{title}

: null} +
+ {title ?

{title}

: null} {description ? ( -

{description}

+

{description}

) : null}
) : null} - {children ?
{children}
: null} -
- {filename ?

{filename}

: null} -
+      {children ? 
{children}
: null} +
+ {filename ?

{filename}

: null} +
           {code}
         
{sourceFiles.length > 0 ? ( -
+
{sourceFiles.map((sourceFile) => (
-

{sourceFile.filename}

+

{sourceFile.filename}

                 {sourceFile.code}
               
diff --git a/apps/example/src/components/docs-mdx/mermaid.tsx b/apps/example/src/components/docs-mdx/mermaid.tsx index 443bd56..c8b64b4 100644 --- a/apps/example/src/components/docs-mdx/mermaid.tsx +++ b/apps/example/src/components/docs-mdx/mermaid.tsx @@ -13,7 +13,7 @@ export interface MermaidProps { export function Mermaid({ chart, children }: MermaidProps) { const source = chart ?? (typeof children === "string" ? children : ""); return ( -
+    
       {source}
     
); diff --git a/apps/example/src/components/docs-mdx/selector.tsx b/apps/example/src/components/docs-mdx/selector.tsx index 3483523..0531341 100644 --- a/apps/example/src/components/docs-mdx/selector.tsx +++ b/apps/example/src/components/docs-mdx/selector.tsx @@ -31,14 +31,14 @@ export function Selector({ const id = useId(); return ( -
+
{label ? ( -