From b12fcfc86358f24cba284359ab286491c725b2c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 02:32:46 +0000 Subject: [PATCH 1/3] Initial plan From a6779f840c5c077b60d2a377fc1a75ecde69863f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 02:47:32 +0000 Subject: [PATCH 2/3] Update fumadocs docs app to latest template patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update package.json: pin fumadocs versions, add postinstall/types:check scripts, remove unused deps (clsx, cva, autoprefixer, etc.) - Update source.config.ts: use pageSchema/metaSchema, add includeProcessedMarkdown for LLM support - Update next.config.mjs: remove webpack hacks, add rewrites for LLM MDX - Update postcss.config.mjs: remove autoprefixer (Tailwind v4) - Update tsconfig.json: add baseUrl, forceConsistentCasingInFileNames, ESNext target - Update global.css: use new fumadocs CSS imports (neutral.css + preset.css) - Update mdx-components.tsx: rename to getMDXComponents pattern - Update lib/utils.ts: simplify cn to twMerge re-export - Move app/source.ts → lib/source.ts with lucideIconsPlugin, getPageImage, getLLMText - Move app/layout.config.tsx → lib/layout.shared.tsx with function pattern + gitConfig - Update docs page: use DocsTitle/DocsDescription/DocsBody from new import path - Update search API: use createFromSource instead of createSearchAPI - Add LLM support: llms.txt, llms-full.txt, per-page .mdx endpoints - Add OG image generation: og/docs/[...slug]/route.tsx - Add AI page-actions component: Copy Markdown, Open in ChatGPT/Claude/GitHub - Remove tailwind.config.js (Tailwind v4 doesn't need config) - Remove unused badge.tsx and button.tsx components Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- .../docs/app/[lang]/blog/[[...slug]]/page.tsx | 14 +- .../docs/app/[lang]/docs/[[...slug]]/page.tsx | 55 +- apps/docs/app/[lang]/docs/layout.tsx | 7 +- apps/docs/app/[lang]/layout.tsx | 26 +- apps/docs/app/[lang]/page.tsx | 4 +- apps/docs/app/api/search/route.ts | 12 +- apps/docs/app/global.css | 17 +- apps/docs/app/layout.config.tsx | 47 -- apps/docs/app/layout.tsx | 6 +- apps/docs/app/llms-full.txt/route.ts | 10 + .../app/llms.mdx/docs/[[...slug]]/route.ts | 23 + apps/docs/app/llms.txt/route.ts | 13 + apps/docs/app/og/docs/[...slug]/route.tsx | 33 + apps/docs/app/source.ts | 14 - apps/docs/components/ai/page-actions.tsx | 159 +++++ apps/docs/components/ui/badge.tsx | 39 -- apps/docs/components/ui/button.tsx | 52 -- apps/docs/lib/layout.shared.tsx | 35 + apps/docs/lib/source.ts | 33 + apps/docs/lib/utils.ts | 7 +- apps/docs/mdx-components.tsx | 8 +- apps/docs/next.config.mjs | 20 +- apps/docs/package.json | 22 +- apps/docs/postcss.config.mjs | 2 - apps/docs/source.config.ts | 20 +- apps/docs/tailwind.config.js | 67 -- apps/docs/tsconfig.json | 9 +- content/docs/references/ai/agent-action.mdx | 435 ------------ content/docs/references/ai/agent.mdx | 43 -- content/docs/references/ai/conversation.mdx | 268 -------- content/docs/references/ai/cost.mdx | 260 ------- content/docs/references/ai/devops-agent.mdx | 159 ----- content/docs/references/ai/feedback-loop.mdx | 43 -- content/docs/references/ai/index.mdx | 1 + content/docs/references/ai/mcp.mdx | 149 ++++ content/docs/references/ai/meta.json | 1 + content/docs/references/ai/model-registry.mdx | 127 ---- content/docs/references/ai/nlq.mdx | 168 ----- content/docs/references/ai/orchestration.mdx | 136 ---- .../docs/references/ai/plugin-development.mdx | 94 --- content/docs/references/ai/predictive.mdx | 157 ----- content/docs/references/ai/rag-pipeline.mdx | 320 --------- content/docs/references/ai/runtime-ops.mdx | 103 --- .../docs/references/api/.!52095!websocket.mdx | 262 -------- content/docs/references/api/analytics.mdx | 47 -- content/docs/references/api/auth.mdx | 78 --- content/docs/references/api/batch.mdx | 77 --- content/docs/references/api/connector.mdx | 7 - content/docs/references/api/contract.mdx | 92 --- content/docs/references/api/discovery.mdx | 41 +- content/docs/references/api/dispatcher.mdx | 55 ++ content/docs/references/api/documentation.mdx | 138 ---- content/docs/references/api/endpoint.mdx | 34 - content/docs/references/api/errors.mdx | 103 --- content/docs/references/api/graphql.mdx | 192 ------ content/docs/references/api/http-cache.mdx | 70 -- content/docs/references/api/hub.mdx | 636 ------------------ content/docs/references/api/identity.mdx | 11 - content/docs/references/api/index.mdx | 4 +- content/docs/references/api/meta.json | 5 +- content/docs/references/api/metadata.mdx | 27 - content/docs/references/api/object.mdx | 26 + content/docs/references/api/odata.mdx | 93 --- .../docs/references/api/package-registry.mdx | 82 --- .../docs/references/api/plugin-rest-api.mdx | 170 +++++ content/docs/references/api/protocol.mdx | 576 ++++++++-------- content/docs/references/api/realtime.mdx | 90 +-- content/docs/references/api/registry.mdx | 172 ----- content/docs/references/api/rest-server.mdx | 99 --- content/docs/references/api/router.mdx | 33 - content/docs/references/api/storage.mdx | 35 - content/docs/references/api/versioning.mdx | 59 ++ content/docs/references/api/view.mdx | 10 - content/docs/references/api/websocket.mdx | 450 ------------- .../docs/references/automation/approval.mdx | 57 -- .../docs/references/automation/connector.mdx | 87 +-- content/docs/references/automation/etl.mdx | 99 --- content/docs/references/automation/events.mdx | 7 - content/docs/references/automation/flow.mdx | 65 -- .../references/automation/state-machine.mdx | 79 --- content/docs/references/automation/sync.mdx | 56 -- .../automation/trigger-registry.mdx | 107 +-- .../docs/references/automation/webhook.mdx | 41 -- .../docs/references/automation/workflow.mdx | 237 ------- content/docs/references/data/analytics.mdx | 86 +-- content/docs/references/data/data-engine.mdx | 331 --------- content/docs/references/data/dataset.mdx | 18 - content/docs/references/data/datasource.mdx | 43 -- content/docs/references/data/document.mdx | 50 -- content/docs/references/data/driver-nosql.mdx | 161 ----- content/docs/references/data/driver-sql.mdx | 45 -- content/docs/references/data/driver.mdx | 74 -- .../docs/references/data/external-lookup.mdx | 33 - content/docs/references/data/field.mdx | 208 ------ content/docs/references/data/filter.mdx | 83 --- content/docs/references/data/hook.mdx | 48 -- content/docs/references/data/mapping.mdx | 34 - content/docs/references/data/meta.json | 1 - content/docs/references/data/metrics.mdx | 38 -- content/docs/references/data/object.mdx | 133 ---- content/docs/references/data/query.mdx | 142 ---- .../docs/references/data/search-engine.mdx | 8 - content/docs/references/data/validation.mdx | 362 ---------- content/docs/references/hub/license.mdx | 41 ++ content/docs/references/hub/meta.json | 10 + .../docs/references/hub/plugin-registry.mdx | 51 ++ .../docs/references/hub/plugin-security.mdx | 86 +++ .../docs/references/hub/registry-config.mdx | 36 + content/docs/references/hub/tenant.mdx | 61 ++ content/docs/references/identity/identity.mdx | 55 -- .../docs/references/identity/organization.mdx | 44 -- content/docs/references/identity/role.mdx | 9 - content/docs/references/identity/scim.mdx | 157 ----- .../docs/references/integration/connector.mdx | 273 +------- content/docs/references/integration/http.mdx | 11 - .../docs/references/integration/mapping.mdx | 12 - .../references/integration/message-queue.mdx | 32 - content/docs/references/integration/misc.mdx | 615 ----------------- .../references/integration/object-storage.mdx | 9 - content/docs/references/kernel/context.mdx | 22 - content/docs/references/kernel/events.mdx | 181 ----- content/docs/references/kernel/feature.mdx | 21 - content/docs/references/kernel/index.mdx | 3 + content/docs/references/kernel/manifest.mdx | 21 - content/docs/references/kernel/meta.json | 7 +- .../kernel/metadata-persistence.mdx | 134 ---- .../references/kernel/package-registry.mdx | 103 --- content/docs/references/kernel/permission.mdx | 8 - .../references/kernel/plugin-capability.mdx | 94 --- .../kernel/plugin-lifecycle-advanced.mdx | 103 --- .../kernel/plugin-lifecycle-events.mdx | 120 ---- .../docs/references/kernel/plugin-loading.mdx | 170 ----- .../references/kernel/plugin-registry.mdx | 85 --- .../docs/references/kernel/plugin-runtime.mdx | 87 +++ .../kernel/plugin-security-advanced.mdx | 110 +-- .../references/kernel/plugin-security.mdx | 97 +-- .../references/kernel/plugin-structure.mdx | 14 - .../references/kernel/plugin-validator.mdx | 35 - .../references/kernel/plugin-versioning.mdx | 81 ++- content/docs/references/kernel/plugin.mdx | 54 +- .../references/kernel/service-registry.mdx | 55 -- .../kernel/startup-orchestrator.mdx | 38 -- content/docs/references/meta.json | 1 + content/docs/references/qa/testing.mdx | 74 -- .../docs/references/security/permission.mdx | 34 - content/docs/references/security/policy.mdx | 48 -- content/docs/references/security/rls.mdx | 59 -- content/docs/references/security/sharing.mdx | 98 --- .../docs/references/security/territory.mdx | 31 - content/docs/references/shared/enums.mdx | 48 ++ content/docs/references/shared/http.mdx | 26 - .../docs/references/shared/identifiers.mdx | 6 - content/docs/references/shared/index.mdx | 2 + content/docs/references/shared/mapping.mdx | 90 --- content/docs/references/shared/meta.json | 3 + .../shared/metadata-persistence.mdx | 26 + .../docs/references/shared/metadata-types.mdx | 28 + content/docs/references/shared/view.mdx | 10 - content/docs/references/studio/index.mdx | 10 + content/docs/references/studio/meta.json | 6 + content/docs/references/studio/plugin.mdx | 169 +++++ content/docs/references/system/audit.mdx | 173 ----- .../docs/references/system/auth-config.mdx | 30 - content/docs/references/system/cache.mdx | 39 -- .../references/system/change-management.mdx | 63 -- .../docs/references/system/collaboration.mdx | 392 ----------- content/docs/references/system/compliance.mdx | 49 -- .../docs/references/system/core-services.mdx | 58 ++ content/docs/references/system/encryption.mdx | 42 -- .../docs/references/system/http-server.mdx | 86 --- content/docs/references/system/index.mdx | 5 +- content/docs/references/system/job.mdx | 104 --- content/docs/references/system/license.mdx | 43 +- content/docs/references/system/logging.mdx | 195 ------ content/docs/references/system/masking.mdx | 30 - .../docs/references/system/message-queue.mdx | 47 -- content/docs/references/system/meta.json | 10 +- .../system/metadata-persistence.mdx | 172 ----- content/docs/references/system/metrics.mdx | 87 ++- content/docs/references/system/migration.mdx | 178 ----- .../docs/references/system/notification.mdx | 65 -- .../docs/references/system/object-storage.mdx | 198 ------ .../references/system/registry-config.mdx | 34 - .../docs/references/system/search-engine.mdx | 47 -- .../references/system/service-registry.mdx | 100 --- content/docs/references/system/tenant.mdx | 106 +-- content/docs/references/system/tracing.mdx | 227 ------- .../docs/references/system/translation.mdx | 10 - content/docs/references/system/worker.mdx | 124 ---- content/docs/references/ui/action.mdx | 29 - content/docs/references/ui/app.mdx | 178 ----- content/docs/references/ui/chart.mdx | 105 --- content/docs/references/ui/component.mdx | 52 -- content/docs/references/ui/dashboard.mdx | 24 - content/docs/references/ui/page.mdx | 68 -- content/docs/references/ui/report.mdx | 57 -- content/docs/references/ui/theme.mdx | 133 ---- content/docs/references/ui/view.mdx | 199 ------ content/docs/references/ui/widget.mdx | 117 ---- pnpm-lock.yaml | 54 +- 200 files changed, 2199 insertions(+), 15170 deletions(-) delete mode 100644 apps/docs/app/layout.config.tsx create mode 100644 apps/docs/app/llms-full.txt/route.ts create mode 100644 apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts create mode 100644 apps/docs/app/llms.txt/route.ts create mode 100644 apps/docs/app/og/docs/[...slug]/route.tsx delete mode 100644 apps/docs/app/source.ts create mode 100644 apps/docs/components/ai/page-actions.tsx delete mode 100644 apps/docs/components/ui/badge.tsx delete mode 100644 apps/docs/components/ui/button.tsx create mode 100644 apps/docs/lib/layout.shared.tsx create mode 100644 apps/docs/lib/source.ts delete mode 100644 apps/docs/tailwind.config.js create mode 100644 content/docs/references/ai/mcp.mdx delete mode 100644 content/docs/references/api/.!52095!websocket.mdx create mode 100644 content/docs/references/api/dispatcher.mdx delete mode 100644 content/docs/references/api/hub.mdx create mode 100644 content/docs/references/api/object.mdx create mode 100644 content/docs/references/api/plugin-rest-api.mdx create mode 100644 content/docs/references/api/versioning.mdx delete mode 100644 content/docs/references/data/metrics.mdx create mode 100644 content/docs/references/hub/license.mdx create mode 100644 content/docs/references/hub/meta.json create mode 100644 content/docs/references/hub/plugin-registry.mdx create mode 100644 content/docs/references/hub/plugin-security.mdx create mode 100644 content/docs/references/hub/registry-config.mdx create mode 100644 content/docs/references/hub/tenant.mdx create mode 100644 content/docs/references/kernel/plugin-runtime.mdx create mode 100644 content/docs/references/shared/enums.mdx create mode 100644 content/docs/references/shared/metadata-persistence.mdx create mode 100644 content/docs/references/shared/metadata-types.mdx create mode 100644 content/docs/references/studio/index.mdx create mode 100644 content/docs/references/studio/meta.json create mode 100644 content/docs/references/studio/plugin.mdx create mode 100644 content/docs/references/system/core-services.mdx delete mode 100644 content/docs/references/system/service-registry.mdx diff --git a/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx index 224d5a0eb..95b343f51 100644 --- a/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx +++ b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx @@ -1,8 +1,8 @@ import { notFound } from 'next/navigation'; -import { blog } from '@/app/source'; -import defaultMdxComponents from 'fumadocs-ui/mdx'; +import { blog } from '@/lib/source'; +import { getMDXComponents } from '@/mdx-components'; import { HomeLayout } from 'fumadocs-ui/layouts/home'; -import { baseOptions } from '@/app/layout.config'; +import { baseOptions } from '@/lib/layout.shared'; import Link from 'next/link'; import { ArrowLeft } from 'lucide-react'; @@ -16,9 +16,7 @@ interface BlogPostData { body: React.ComponentType; } -const components = { - ...defaultMdxComponents, -} as any; +const components = getMDXComponents() as any; export default async function BlogPage({ params, @@ -32,7 +30,7 @@ export default async function BlogPage({ const posts = blog.getPages(); return ( - +

Blog

@@ -114,7 +112,7 @@ export default async function BlogPage({ const MDX = page.data.body; return ( - +
; @@ -26,19 +17,33 @@ export default async function Page(props: { const page = source.getPage(params.slug ?? [], params.lang); if (!page) notFound(); - const data = page.data as any; - const Content = data.body; + const MDX = page.data.body; return ( - + + {page.data.title} + {page.data.description} +
+ + +
-

{page.data.title}

- {page.data.description && ( -

- {page.data.description} -

- )} - +
); diff --git a/apps/docs/app/[lang]/docs/layout.tsx b/apps/docs/app/[lang]/docs/layout.tsx index 06ecb816d..38c912a62 100644 --- a/apps/docs/app/[lang]/docs/layout.tsx +++ b/apps/docs/app/[lang]/docs/layout.tsx @@ -1,8 +1,7 @@ -import { source } from '@/app/source'; -import type { Metadata } from 'next'; +import { source } from '@/lib/source'; import { DocsLayout } from 'fumadocs-ui/layouts/docs'; import type { ReactNode } from 'react'; -import { baseOptions } from '@/app/layout.config'; +import { baseOptions } from '@/lib/layout.shared'; export default async function Layout({ params, @@ -16,7 +15,7 @@ export default async function Layout({ return ( {children} diff --git a/apps/docs/app/[lang]/layout.tsx b/apps/docs/app/[lang]/layout.tsx index e2fcf3d95..f1c6ad457 100644 --- a/apps/docs/app/[lang]/layout.tsx +++ b/apps/docs/app/[lang]/layout.tsx @@ -18,21 +18,17 @@ export default async function LanguageLayout({ const { lang } = await params; return ( - - - ({ - name: LANGUAGE_NAMES[l] || l, - locale: l, - })), - }} - > - {children} - - - + ({ + name: LANGUAGE_NAMES[l] || l, + locale: l, + })), + }} + > + {children} + ); } diff --git a/apps/docs/app/[lang]/page.tsx b/apps/docs/app/[lang]/page.tsx index 649a0e9ec..46ac5d4fd 100644 --- a/apps/docs/app/[lang]/page.tsx +++ b/apps/docs/app/[lang]/page.tsx @@ -1,6 +1,6 @@ import { Database, Monitor, HardDrive, ShieldCheck, Puzzle, Code2, Rocket, Users, Blocks, LucideIcon } from 'lucide-react'; import { HomeLayout } from 'fumadocs-ui/layouts/home'; -import { baseOptions } from '@/app/layout.config'; +import { baseOptions } from '@/lib/layout.shared'; import { getHomepageTranslations } from '@/lib/homepage-i18n'; import { HeroSection } from '@/components/hero-section'; import { CodePreview } from '@/components/code-preview'; @@ -91,7 +91,7 @@ export default async function HomePage({ ]; return ( - +
{/* Hero Section */} diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts index afb3bf078..b02d7cd3a 100644 --- a/apps/docs/app/api/search/route.ts +++ b/apps/docs/app/api/search/route.ts @@ -1,10 +1,6 @@ -import { source } from '@/app/source'; -import { createSearchAPI } from 'fumadocs-core/search/server'; +import { source } from '@/lib/source'; +import { createFromSource } from 'fumadocs-core/search/server'; -export const { GET } = createSearchAPI('simple', { - indexes: source.getPages().map((page) => ({ - title: page.data.title ?? 'Untitled', - content: page.data.description ?? '', - url: page.url, - })), +export const { GET } = createFromSource(source, { + language: 'english', }); diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index c1d76161a..50b3bc296 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -1,14 +1,3 @@ -@import "tailwindcss"; -@import "fumadocs-ui/style.css"; - -@layer base { - :root { - --radius: 0.5rem; - } -} - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; diff --git a/apps/docs/app/layout.config.tsx b/apps/docs/app/layout.config.tsx deleted file mode 100644 index 57c25a799..000000000 --- a/apps/docs/app/layout.config.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; -import Image from 'next/image'; - -export const baseOptions: BaseLayoutProps = { - nav: { - title: ( -
- ObjectStack - ObjectStack -
- ), - transparentMode: 'top', - }, - links: [ - { - text: 'Documentation', - url: '/docs/', - active: 'nested-url', - }, - // { - // text: 'Blog', - // url: '/blog', - // active: 'nested-url', - // }, - // { - // text: 'Concepts', - // url: '/docs/concepts/manifesto', - // active: 'nested-url', - // }, - // { - // text: 'Specs', - // url: '/docs/specifications/data/architecture', - // active: 'nested-url', - // }, - // { - // text: 'Reference', - // url: '/docs/references/data/core/Object', - // active: 'nested-url', - // }, - ], - githubUrl: 'https://github.com/objectstack-ai/spec', -}; diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx index f60456680..a1dd50f87 100644 --- a/apps/docs/app/layout.tsx +++ b/apps/docs/app/layout.tsx @@ -1,8 +1,6 @@ import './global.css'; -import { redirect } from 'next/navigation'; import type { ReactNode } from 'react'; import type { Metadata } from 'next'; -import { i18n } from '@/lib/i18n'; export const metadata: Metadata = { title: { @@ -16,11 +14,9 @@ export const metadata: Metadata = { }; export default function RootLayout({ children }: { children: ReactNode }) { - // Root layout is only used for redirects with middleware - // The actual layout is in [lang]/layout.tsx return ( - {children} + {children} ); } diff --git a/apps/docs/app/llms-full.txt/route.ts b/apps/docs/app/llms-full.txt/route.ts new file mode 100644 index 000000000..d494d2cbb --- /dev/null +++ b/apps/docs/app/llms-full.txt/route.ts @@ -0,0 +1,10 @@ +import { getLLMText, source } from '@/lib/source'; + +export const revalidate = false; + +export async function GET() { + const scan = source.getPages().map(getLLMText); + const scanned = await Promise.all(scan); + + return new Response(scanned.join('\n\n')); +} diff --git a/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts b/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts new file mode 100644 index 000000000..fe641f68e --- /dev/null +++ b/apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts @@ -0,0 +1,23 @@ +import { getLLMText, source } from '@/lib/source'; +import { notFound } from 'next/navigation'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: { params: Promise<{ slug?: string[] }> }, +) { + const { slug } = await params; + const page = source.getPage(slug); + if (!page) notFound(); + + return new Response(await getLLMText(page), { + headers: { + 'Content-Type': 'text/markdown', + }, + }); +} + +export function generateStaticParams() { + return source.generateParams(); +} diff --git a/apps/docs/app/llms.txt/route.ts b/apps/docs/app/llms.txt/route.ts new file mode 100644 index 000000000..6639c252a --- /dev/null +++ b/apps/docs/app/llms.txt/route.ts @@ -0,0 +1,13 @@ +import { source } from '@/lib/source'; + +export const revalidate = false; + +export async function GET() { + const lines: string[] = []; + lines.push('# Documentation'); + lines.push(''); + for (const page of source.getPages()) { + lines.push(`- [${page.data.title}](${page.url}): ${page.data.description}`); + } + return new Response(lines.join('\n')); +} diff --git a/apps/docs/app/og/docs/[...slug]/route.tsx b/apps/docs/app/og/docs/[...slug]/route.tsx new file mode 100644 index 000000000..5efbc353e --- /dev/null +++ b/apps/docs/app/og/docs/[...slug]/route.tsx @@ -0,0 +1,33 @@ +import { getPageImage, source } from '@/lib/source'; +import { notFound } from 'next/navigation'; +import { ImageResponse } from 'next/og'; +import { generate as DefaultImage } from 'fumadocs-ui/og'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: { params: Promise<{ slug: string[] }> }, +) { + const { slug } = await params; + const page = source.getPage(slug.slice(0, -1)); + if (!page) notFound(); + + return new ImageResponse( + , + { + width: 1200, + height: 630, + }, + ); +} + +export function generateStaticParams() { + return source.getPages().map((page) => ({ + slug: getPageImage(page).segments, + })); +} diff --git a/apps/docs/app/source.ts b/apps/docs/app/source.ts deleted file mode 100644 index badf8aa26..000000000 --- a/apps/docs/app/source.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { docs, blog as blogCollection } from 'fumadocs-mdx:collections/server'; -import { loader } from 'fumadocs-core/source'; -import { i18n } from '@/lib/i18n'; - -export const source = loader({ - baseUrl: '/docs', - i18n, - source: docs.toFumadocsSource(), -}); - -export const blog = loader({ - baseUrl: '/blog', - source: blogCollection.toFumadocsSource(), -}); diff --git a/apps/docs/components/ai/page-actions.tsx b/apps/docs/components/ai/page-actions.tsx new file mode 100644 index 000000000..7bd762c0a --- /dev/null +++ b/apps/docs/components/ai/page-actions.tsx @@ -0,0 +1,159 @@ +'use client'; +import { useMemo, useState } from 'react'; +import { Check, ChevronDown, Copy, ExternalLinkIcon } from 'lucide-react'; +import { cn } from '@/lib/utils'; +import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button'; +import { buttonVariants } from 'fumadocs-ui/components/ui/button'; +import { Popover, PopoverContent, PopoverTrigger } from 'fumadocs-ui/components/ui/popover'; + +const cache = new Map(); + +export function LLMCopyButton({ + /** + * A URL to fetch the raw Markdown/MDX content of page + */ + markdownUrl, +}: { + markdownUrl: string; +}) { + const [isLoading, setLoading] = useState(false); + const [checked, onClick] = useCopyButton(async () => { + const cached = cache.get(markdownUrl); + if (cached) return navigator.clipboard.writeText(cached); + + setLoading(true); + + try { + await navigator.clipboard.write([ + new ClipboardItem({ + 'text/plain': fetch(markdownUrl).then(async (res) => { + const content = await res.text(); + cache.set(markdownUrl, content); + + return content; + }), + }), + ]); + } finally { + setLoading(false); + } + }); + + return ( + + ); +} + +export function ViewOptions({ + markdownUrl, + githubUrl, +}: { + /** + * A URL to the raw Markdown/MDX content of page + */ + markdownUrl: string; + + /** + * Source file URL on GitHub + */ + githubUrl: string; +}) { + const items = useMemo(() => { + const fullMarkdownUrl = + typeof window !== 'undefined' ? new URL(markdownUrl, window.location.origin) : 'loading'; + const q = `Read ${fullMarkdownUrl}, I want to ask questions about it.`; + + return [ + { + title: 'Open in GitHub', + href: githubUrl, + icon: ( + + GitHub + + + ), + }, + { + title: 'Open in ChatGPT', + href: `https://chatgpt.com/?${new URLSearchParams({ + hints: 'search', + q, + })}`, + icon: ( + + OpenAI + + + ), + }, + { + title: 'Open in Claude', + href: `https://claude.ai/new?${new URLSearchParams({ + q, + })}`, + icon: ( + + Anthropic + + + ), + }, + ]; + }, [githubUrl, markdownUrl]); + + return ( + + + Open + + + + {items.map((item) => ( + + {item.icon} + {item.title} + + + ))} + + + ); +} diff --git a/apps/docs/components/ui/badge.tsx b/apps/docs/components/ui/badge.tsx deleted file mode 100644 index ef315a633..000000000 --- a/apps/docs/components/ui/badge.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils" - -const badgeVariants = cva( - "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", - secondary: - "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - outline: "text-foreground border-border", - success: - "border-transparent bg-green-500 text-white hover:bg-green-500/80", - warning: - "border-transparent bg-yellow-500 text-white hover:bg-yellow-500/80", - destructive: - "border-transparent bg-red-500 text-white hover:bg-red-500/80", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} - -function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) -} - -export { Badge, badgeVariants } diff --git a/apps/docs/components/ui/button.tsx b/apps/docs/components/ui/button.tsx deleted file mode 100644 index 9b9557e20..000000000 --- a/apps/docs/components/ui/button.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils" - -const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", - { - variants: { - variant: { - default: - "bg-primary text-primary-foreground shadow-lg shadow-primary/20 hover:bg-primary/90 hover:scale-105 hover:shadow-primary/30", - secondary: - "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", - outline: - "border border-border bg-card/50 backdrop-blur-sm hover:bg-accent hover:text-accent-foreground hover:scale-105", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-12 px-8 py-3", - sm: "h-9 px-4 py-2", - lg: "h-14 px-10 py-4", - icon: "h-10 w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean -} - -const Button = React.forwardRef( - ({ className, variant, size, ...props }, ref) => { - return ( -