Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
bun-version: 1.3.14

- run: bun install --frozen-lockfile

Expand Down
27 changes: 27 additions & 0 deletions apps/docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# deps
/node_modules

# generated content
.source

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts
.open-next
45 changes: 45 additions & 0 deletions apps/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# docs

This is a Next.js application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).

Run development server:

```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```

Open http://localhost:3000 with your browser to see the result.

## Explore

In the project, you can see:

- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content.
- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep.

| Route | Description |
| ------------------------- | ------------------------------------------------------ |
| `app/(home)` | The route group for your landing page and other pages. |
| `app/docs` | The documentation layout and pages. |
| `app/api/search/route.ts` | The Route Handler for search. |

### Fumadocs MDX

A `source.config.ts` config file has been included, you can customise different options like frontmatter schema.

Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details.

## Learn More

To learn more about Next.js and Fumadocs, take a look at the following
resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs
12 changes: 12 additions & 0 deletions apps/docs/app/[[...slug]]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ReactNode } from 'react';
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/lib/layout.shared';

export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.getPageTree()} {...baseOptions()}>
{children}
</DocsLayout>
);
}
72 changes: 72 additions & 0 deletions apps/docs/app/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { getPageImage, source } from '@/lib/source';
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
MarkdownCopyButton,
ViewOptionsPopover,
} from 'fumadocs-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/components/mdx';
import type { Metadata } from 'next';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import { gitConfig } from '@/lib/layout.shared';

type PageParams = {
slug?: string[];
};

export default async function Page({ params }: { params: Promise<PageParams> }) {
const { slug } = await params;
const page = source.getPage(slug);
if (!page) notFound();

const MDX = page.data.body;

return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription className="mb-0">{page.data.description}</DocsDescription>
<div className="flex flex-row gap-2 items-center border-b pb-6">
<MarkdownCopyButton markdownUrl={`${page.url}.mdx`} />
<ViewOptionsPopover
markdownUrl={`${page.url}.mdx`}
githubUrl={`https://github.com/${gitConfig.user}/${gitConfig.repo}/blob/${gitConfig.branch}/content/docs/${page.path}`}
/>
</div>
<DocsBody>
<MDX
components={getMDXComponents({
a: createRelativeLink(source, page),
})}
/>
</DocsBody>
</DocsPage>
);
}

export function generateStaticParams() {
const params = source.generateParams();
return params.some((param) => !param.slug || param.slug.length === 0)
? params
: [{ slug: [] }, ...params];
}

export async function generateMetadata({
params,
}: {
params: Promise<PageParams>;
}): Promise<Metadata> {
const { slug } = await params;
const page = source.getPage(slug);
if (!page) notFound();

return {
title: page.data.title,
description: page.data.description,
openGraph: {
images: getPageImage(page).url,
},
};
}
7 changes: 7 additions & 0 deletions apps/docs/app/api/search/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(source, {
// https://docs.orama.com/docs/orama-js/supported-languages
language: 'english',
});
3 changes: 3 additions & 0 deletions apps/docs/app/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
42 changes: 42 additions & 0 deletions apps/docs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { Metadata } from 'next';
import { RootProvider } from 'fumadocs-ui/provider/next';
import './global.css';
import { Inter } from 'next/font/google';

const inter = Inter({
subsets: ['latin'],
});

const description = 'Documentation for Kyora, the runtime observability SDK for coding agents.';

export const metadata: Metadata = {
metadataBase: new URL('https://docs.kyora.sh'),
title: {
default: 'Kyora Docs',
template: '%s | Kyora Docs',
},
description,
applicationName: 'Kyora Docs',
openGraph: {
type: 'website',
url: 'https://docs.kyora.sh',
title: 'Kyora Docs',
siteName: 'Kyora Docs',
description,
},
twitter: {
card: 'summary_large_image',
title: 'Kyora Docs',
description,
},
};

export default function Layout({ children }: LayoutProps<'/'>) {
return (
<html lang="en" className={inter.className} suppressHydrationWarning>
<body className="flex flex-col min-h-screen">
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}
10 changes: 10 additions & 0 deletions apps/docs/app/llms-full.txt/route.ts
Original file line number Diff line number Diff line change
@@ -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'));
}
20 changes: 20 additions & 0 deletions apps/docs/app/llms.mdx/docs/[[...slug]]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { getLLMText, source } from '@/lib/source';
import { notFound } from 'next/navigation';

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/docs/[[...slug]]'>) {
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();
}
8 changes: 8 additions & 0 deletions apps/docs/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { source } from '@/lib/source';
import { llms } from 'fumadocs-core/source';

export const revalidate = false;

export function GET() {
return new Response(llms(source).index());
}
28 changes: 28 additions & 0 deletions apps/docs/app/og/docs/[...slug]/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getPageImage, source } from '@/lib/source';
import { notFound } from 'next/navigation';
import { ImageResponse } from '@takumi-rs/image-response';
import { generate as DefaultImage } from 'fumadocs-ui/og/takumi';

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
const { slug } = await params;
const page = source.getPage(slug.slice(0, -1));
if (!page) notFound();

return new ImageResponse(
<DefaultImage title={page.data.title} description={page.data.description} site="Kyora Docs" />,
{
width: 1200,
height: 630,
format: 'webp',
},
);
}

export function generateStaticParams() {
return source.getPages().map((page) => ({
lang: page.locale,
slug: getPageImage(page).segments,
}));
}
15 changes: 15 additions & 0 deletions apps/docs/components/mdx.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import defaultMdxComponents from 'fumadocs-ui/mdx';
import type { MDXComponents } from 'mdx/types';

export function getMDXComponents(components?: MDXComponents) {
return {
...defaultMdxComponents,
...components,
} satisfies MDXComponents;
}

export const useMDXComponents = getMDXComponents;

declare global {
type MDXProvidedComponents = ReturnType<typeof getMDXComponents>;
}
13 changes: 13 additions & 0 deletions apps/docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: Hello World
description: Your first document
---

Welcome to the docs! You can start writing documents in `/content/docs`.

## What is Next?

<Cards>
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
</Cards>
17 changes: 17 additions & 0 deletions apps/docs/content/docs/test.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Components
description: Components
---

## Code Block

```js
console.log('Hello World');
```

## Cards

<Cards>
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
</Cards>
15 changes: 15 additions & 0 deletions apps/docs/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defineConfig, globalIgnores } from 'eslint/config';
import nextVitals from 'eslint-config-next/core-web-vitals';

const eslintConfig = defineConfig([
...nextVitals,
globalIgnores([
'.next/**',
'out/**',
'build/**',
'next-env.d.ts',
'.source/**',
]),
]);

export default eslintConfig;
1 change: 1 addition & 0 deletions apps/docs/lib/cn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { twMerge as cn } from 'tailwind-merge';
16 changes: 16 additions & 0 deletions apps/docs/lib/layout.shared.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';

export const gitConfig = {
user: 'eliahilse',
repo: 'kyora',
branch: 'main',
};

export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'Kyora Docs',
},
githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
};
}
Loading
Loading