mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
feat(docs): add Fumadocs site workspace
This commit is contained in:
parent
cb9ab25456
commit
572d515db0
28 changed files with 3979 additions and 84 deletions
7
docs/app/(home)/layout.tsx
Normal file
7
docs/app/(home)/layout.tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { HomeLayout } from "fumadocs-ui/layouts/home";
|
||||
import type { ReactNode } from "react";
|
||||
import { baseOptions } from "@/app/layout.config";
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
|
||||
}
|
||||
5
docs/app/(home)/page.tsx
Normal file
5
docs/app/(home)/page.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { redirect } from "next/navigation";
|
||||
|
||||
export default function HomePage() {
|
||||
redirect("/docs/getting-started/introduction");
|
||||
}
|
||||
12
docs/app/docs/layout.tsx
Normal file
12
docs/app/docs/layout.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { source } from "@/lib/source";
|
||||
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
||||
import type { ReactNode } from "react";
|
||||
import { baseOptions } from "@/app/layout.config";
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<DocsLayout tree={source.pageTree} {...baseOptions}>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
10
docs/app/layout.config.tsx
Normal file
10
docs/app/layout.config.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
||||
import { Logo } from "@/components/logo";
|
||||
|
||||
export const baseOptions: BaseLayoutProps = {
|
||||
nav: {
|
||||
title: <Logo />,
|
||||
transparentMode: "top",
|
||||
},
|
||||
githubUrl: "https://github.com/kaelio/ktx",
|
||||
};
|
||||
44
docs/app/layout.tsx
Normal file
44
docs/app/layout.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import "./global.css";
|
||||
import { RootProvider } from "fumadocs-ui/provider";
|
||||
import { Outfit, Inter, Geist_Mono } from "next/font/google";
|
||||
import type { ReactNode } from "react";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
const outfit = Outfit({
|
||||
variable: "--font-outfit",
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "600", "700", "800"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
template: "%s | KTX Docs",
|
||||
default: "KTX Docs",
|
||||
},
|
||||
description:
|
||||
"Open-source context infrastructure that makes agentic analytics reliable.",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`${outfit.variable} ${inter.variable} ${geistMono.variable}`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<body>
|
||||
<RootProvider>{children}</RootProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
56
docs/components/logo.tsx
Normal file
56
docs/components/logo.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
export function Logo() {
|
||||
return (
|
||||
<div className="flex items-center gap-2 group">
|
||||
<div className="relative flex items-center justify-center transition-transform duration-300 ease-out group-hover:rotate-[-4deg]">
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="ktx-grad-a" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stopColor="var(--color-fd-primary)" />
|
||||
<stop offset="100%" stopColor="var(--color-fd-primary)" stopOpacity="0.55" />
|
||||
</linearGradient>
|
||||
<linearGradient id="ktx-grad-b" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stopColor="var(--color-fd-primary)" stopOpacity="0.85" />
|
||||
<stop offset="100%" stopColor="var(--color-fd-primary)" stopOpacity="0.4" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
{/* Bottom layer */}
|
||||
<path
|
||||
d="M3 17 L12 21.5 L21 17 L12 12.5 Z"
|
||||
fill="url(#ktx-grad-a)"
|
||||
opacity="0.4"
|
||||
/>
|
||||
{/* Middle layer */}
|
||||
<path
|
||||
d="M3 12 L12 16.5 L21 12 L12 7.5 Z"
|
||||
fill="url(#ktx-grad-b)"
|
||||
opacity="0.7"
|
||||
/>
|
||||
{/* Top layer */}
|
||||
<path
|
||||
d="M3 7 L12 11.5 L21 7 L12 2.5 Z"
|
||||
fill="var(--color-fd-primary)"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
className="text-[15px] font-semibold text-fd-foreground tracking-tight"
|
||||
style={{ fontFamily: "var(--font-display), var(--font-sans), sans-serif" }}
|
||||
>
|
||||
KTX
|
||||
</span>
|
||||
<span
|
||||
className="text-[13px] font-medium text-fd-muted-foreground/80 tracking-tight border-l border-fd-border pl-2 ml-0.5"
|
||||
style={{ fontFamily: "var(--font-display), var(--font-sans), sans-serif" }}
|
||||
>
|
||||
Docs
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
58
docs/components/scroll-reveal.tsx
Normal file
58
docs/components/scroll-reveal.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect, useRef, type ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
stagger?: boolean;
|
||||
threshold?: number;
|
||||
};
|
||||
|
||||
export function ScrollReveal({
|
||||
children,
|
||||
className = "",
|
||||
stagger = false,
|
||||
threshold = 0.1,
|
||||
}: Props) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const node = ref.current;
|
||||
if (!node) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add("visible");
|
||||
if (stagger) {
|
||||
entry.target.querySelectorAll(".rv").forEach((el) => {
|
||||
el.classList.add("visible");
|
||||
});
|
||||
}
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ threshold, rootMargin: "0px 0px -40px 0px" }
|
||||
);
|
||||
|
||||
if (stagger) {
|
||||
observer.observe(node);
|
||||
} else {
|
||||
node.querySelectorAll(".rv").forEach((el) => observer.observe(el));
|
||||
}
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, [stagger, threshold]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`${stagger ? "rv rv-stagger" : ""} ${className}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
56
docs/components/terminal-preview.tsx
Normal file
56
docs/components/terminal-preview.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
export function TerminalPreview() {
|
||||
return (
|
||||
<div className="terminal-frame sheen w-full max-w-[560px]">
|
||||
<div className="terminal-head">
|
||||
<span className="terminal-dot" style={{ background: "#ff5f57" }} />
|
||||
<span className="terminal-dot" style={{ background: "#febc2e" }} />
|
||||
<span className="terminal-dot" style={{ background: "#28c840" }} />
|
||||
<span className="ml-2 text-[11px] text-zinc-500 font-medium tracking-wide">
|
||||
~/analytics
|
||||
</span>
|
||||
</div>
|
||||
<div className="terminal-body">
|
||||
<div>
|
||||
<span className="term-prompt">$</span>{" "}
|
||||
<span className="term-cmd">ktx setup</span>
|
||||
</div>
|
||||
<div className="h-2" />
|
||||
<div className="term-dim">◆ Welcome to KTX setup</div>
|
||||
<div className="term-dim">│</div>
|
||||
<div>
|
||||
<span className="term-dim">◇</span>{" "}
|
||||
<span className="term-key">LLM</span>{" "}
|
||||
<span className="term-ok">✓ claude-sonnet-4-6</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="term-dim">◇</span>{" "}
|
||||
<span className="term-key">Embeddings</span>{" "}
|
||||
<span className="term-ok">✓ openai · text-embedding-3-small</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="term-dim">◇</span>{" "}
|
||||
<span className="term-key">Database</span>{" "}
|
||||
<span className="term-ok">✓ postgres-warehouse · 42 tables</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="term-dim">◇</span>{" "}
|
||||
<span className="term-key">Sources</span>{" "}
|
||||
<span className="term-ok">✓ dbt-main · 218 models</span>
|
||||
</div>
|
||||
<div className="h-2" />
|
||||
<div className="term-info">◐ Building context for agents…</div>
|
||||
<div className="pl-3 text-[12px] term-dim">
|
||||
enriching schema · detecting relationships · ingesting dbt
|
||||
</div>
|
||||
<div className="h-2" />
|
||||
<div className="term-ok">✓ KTX context is ready for agents.</div>
|
||||
<div className="h-2" />
|
||||
<div>
|
||||
<span className="term-prompt">$</span>{" "}
|
||||
<span className="term-cmd">ktx serve</span>
|
||||
<span className="term-cursor ml-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -88,16 +88,7 @@ The fixture runs in multiple modes to isolate the contribution of each pipeline
|
|||
|
||||
## Results
|
||||
|
||||
On the default configuration (`accept_threshold: 0.85`, `review_threshold: 0.55`, `llm_proposals: false`):
|
||||
|
||||
```text
|
||||
Accepted: 9
|
||||
Review: 0
|
||||
Rejected: 0
|
||||
Skipped: 0
|
||||
```
|
||||
|
||||
All 9 ground-truth relationships are detected and accepted with no false positives and no relationships left in the review tier. Primary keys are correctly inferred for all 6 tables.
|
||||
Results for the default configuration will be added after the benchmark run is finalized.
|
||||
|
||||
## Reproducing the benchmark
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Benchmarks",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["link-detection"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"title": "CLI Reference",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": [
|
||||
"ktx-setup",
|
||||
"ktx-connection",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Community",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["contributing"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Concepts",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["the-context-layer", "context-as-code"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Getting Started",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["introduction", "quickstart"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Guides",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["building-context", "writing-context", "serving-agents"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"title": "Integrations",
|
||||
"defaultOpen": false,
|
||||
"defaultOpen": true,
|
||||
"pages": ["primary-sources", "context-sources", "agent-clients"]
|
||||
}
|
||||
|
|
|
|||
7
docs/lib/source.ts
Normal file
7
docs/lib/source.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { docs } from "@/.source";
|
||||
import { loader } from "fumadocs-core/source";
|
||||
|
||||
export const source = loader({
|
||||
source: docs.toFumadocsSource(),
|
||||
baseUrl: "/docs",
|
||||
});
|
||||
6
docs/next-env.d.ts
vendored
Normal file
6
docs/next-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference path="./.next/types/routes.d.ts" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
8
docs/next.config.mjs
Normal file
8
docs/next.config.mjs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { createMDX } from "fumadocs-mdx/next";
|
||||
|
||||
const withMDX = createMDX();
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const config = {};
|
||||
|
||||
export default withMDX(config);
|
||||
26
docs/package.json
Normal file
26
docs/package.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "ktx-docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"fumadocs-core": "15.7.13",
|
||||
"fumadocs-mdx": "11.10.1",
|
||||
"fumadocs-ui": "15.7.13",
|
||||
"next": "^15",
|
||||
"react": "19.2.6",
|
||||
"react-dom": "19.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"typescript": "^5.9",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"tailwindcss": "^4"
|
||||
}
|
||||
}
|
||||
7
docs/postcss.config.mjs
Normal file
7
docs/postcss.config.mjs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const config = {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
9
docs/source.config.ts
Normal file
9
docs/source.config.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { defineDocs, defineConfig } from "fumadocs-mdx/config";
|
||||
|
||||
export const docs = defineDocs({
|
||||
dir: "content/docs",
|
||||
});
|
||||
|
||||
export default defineConfig({
|
||||
mdxOptions: {},
|
||||
});
|
||||
41
docs/tsconfig.json
Normal file
41
docs/tsconfig.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".source/**/*.ts",
|
||||
"next-env.d.ts",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue