docs: clarify getting started introduction (#120)

This commit is contained in:
Luca Martial 2026-05-16 13:25:37 -04:00 committed by GitHub
parent b318671d31
commit c7e6b5001d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 167 additions and 69 deletions

View file

@ -1,31 +1,48 @@
import type { ReactNode } from "react";
type SourceInput = {
name: string;
sources: string[];
detail: string;
signal: string;
accent: string;
};
const sourceInputs = [
{
name: "Warehouse schema",
name: "Database structure",
sources: [
"Postgres",
"Snowflake",
"BigQuery",
"and many others",
],
detail: "tables, columns, types, constraints, row counts",
signal: "grounds definitions in live database structure",
accent: "border-fd-primary",
},
{
name: "Metabase and query history",
name: "BI and usage evidence",
sources: ["Metabase", "Looker"],
detail: "historic SQL, questions, dashboards, usage patterns",
signal: "extracts joins, filters, grain, and trusted examples",
accent: "border-orange-500",
},
{
name: "dbt, MetricFlow, LookML",
name: "Semantic modeling",
sources: ["dbt", "MetricFlow", "LookML"],
detail: "models, metrics, dimensions, explores, joins",
signal: "maps existing modeling logic into semantic entities",
accent: "border-amber-500",
},
{
name: "Company documentation",
detail: "Notion pages, policies, caveats, analyst notes",
sources: ["Notion"],
detail: "Notion pages, policies, caveats",
signal: "links business language back to semantic references",
accent: "border-slate-500 dark:border-cyan-200",
},
];
] satisfies SourceInput[];
const ingestSteps = [
{
@ -99,20 +116,16 @@ export function ProductMechanics() {
aria-labelledby="mechanics-title"
>
<div className="max-w-3xl">
<p className="mb-2 text-xs font-semibold uppercase tracking-wide text-fd-primary">
Product mechanics
</p>
<h2
id="mechanics-title"
className="text-xl font-semibold tracking-normal text-fd-foreground sm:text-2xl"
style={{ fontFamily: "var(--font-display)" }}
>
A semantic compiler for analytics agents
How KTX works
</h2>
<p className="mt-3 text-sm leading-6 text-fd-muted-foreground">
KTX builds typed semantic files, links wiki context back to those
entities, validates the model against database evidence, then compiles
agent requests into executable SQL.
KTX reads source evidence, writes local context files, and gives
agents semantic search, validation, SQL, and provenance.
</p>
</div>
@ -133,41 +146,44 @@ function IngestionDiagram() {
<DiagramHeader
eyebrow="Ingestion"
id="ingestion-diagram-title"
title="Messy source evidence becomes structured state"
body="The important step is reconciliation: KTX turns loose evidence into files agents can validate, edit, and compile against."
title="Build context from source evidence"
body="KTX reconciles loose metadata, SQL, BI usage, and documentation into files agents can validate and edit."
/>
<div className="grid gap-0 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]">
<section className="border-b border-fd-border p-4 lg:border-r lg:border-b-0">
<div className="grid gap-0 lg:grid-cols-[minmax(0,0.94fr)_minmax(0,1.06fr)]">
<section className="flex flex-col border-b border-fd-border p-4 lg:border-r lg:border-b-0">
<ColumnLabel>Inputs KTX reads</ColumnLabel>
<div className="grid gap-2 sm:grid-cols-2">
<div className="grid flex-1 auto-rows-fr gap-2">
{sourceInputs.map((source) => (
<div
key={source.name}
className={`border-l-2 bg-fd-background px-3 py-2 ${source.accent}`}
className={`grid min-h-0 gap-2 border-l-2 bg-fd-background px-3 py-2 sm:grid-cols-[minmax(0,1fr)_minmax(6.5rem,0.42fr)] sm:items-center ${source.accent}`}
>
<p className="text-sm font-semibold text-fd-foreground">
{source.name}
</p>
<p className="mt-0.5 text-xs leading-5 text-fd-muted-foreground">
{source.detail}
</p>
<p className="mt-1 text-xs leading-5 text-fd-primary">
{source.signal}
</p>
<div className="min-w-0">
<p className="text-sm font-semibold text-fd-foreground">
{source.name}
</p>
<p className="mt-0.5 text-xs leading-4 text-fd-muted-foreground">
{source.detail}
</p>
<p className="mt-1 text-xs leading-4 text-fd-primary">
{source.signal}
</p>
</div>
<SourceList sources={source.sources} />
</div>
))}
</div>
</section>
<section className="bg-fd-muted/35 p-4">
<ColumnLabel>KTX builds the model</ColumnLabel>
<div className="grid gap-3 xl:grid-cols-[minmax(0,0.85fr)_minmax(0,1fr)]">
<div className="rounded-md border border-fd-border bg-[#102226] p-4 text-white dark:bg-[#0b181b]">
<section className="flex flex-col bg-fd-muted/35 p-4">
<ColumnLabel>KTX transforms evidence</ColumnLabel>
<div className="flex flex-col gap-3">
<div className="rounded-md border border-fd-border bg-[#102226] p-3 text-white dark:bg-[#0b181b]">
<p className="mb-3 text-[11px] font-semibold uppercase tracking-wide text-cyan-200">
Ingest pipeline
KTX builds the model
</p>
<ol className="space-y-3">
<ol className="grid gap-3">
{ingestSteps.map((step, index) => (
<PipelineStep
key={step.title}
@ -180,10 +196,15 @@ function IngestionDiagram() {
</ol>
</div>
<div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-1">
{artifacts.map((artifact) => (
<Artifact key={artifact.path} {...artifact} />
))}
<div className="border-t border-fd-border/80 pt-3">
<p className="mb-2 text-[11px] font-semibold uppercase tracking-wide text-fd-muted-foreground">
Outputs KTX writes
</p>
<div className="grid gap-2 sm:grid-cols-2">
{artifacts.map((artifact) => (
<Artifact key={artifact.path} {...artifact} />
))}
</div>
</div>
</div>
</section>
@ -201,8 +222,8 @@ function RuntimeDiagram() {
<DiagramHeader
eyebrow="Runtime"
id="runtime-diagram-title"
title="A tiny semantic request becomes a planned, executable query"
body="The agent names the business intent. KTX resolves the semantic model, checks the shape, compiles SQL, and can execute with row limits."
title="Run agent requests through the model"
body="Agents send business intent. KTX resolves fields, checks joins and grain, compiles SQL, and can execute with row limits."
/>
<div className="grid gap-0 lg:grid-cols-[minmax(0,0.82fr)_minmax(0,1.18fr)]">
@ -374,7 +395,7 @@ function PipelineStep({
<span
className={
dark
? "mt-0.5 block break-words text-xs leading-5 text-cyan-50/75"
? "mt-0.5 block break-words text-xs leading-5 text-cyan-50/75"
: "mt-0.5 block break-words text-xs leading-5 text-fd-muted-foreground"
}
>
@ -393,6 +414,42 @@ function ColumnLabel({ children }: { children: ReactNode }) {
);
}
function SourceList({
sources,
}: {
sources: string[];
}) {
return (
<div
className="min-w-0 border-t border-fd-border/70 pt-2 sm:border-t-0 sm:border-l sm:pl-3 sm:pt-0"
aria-label="Sources"
>
<p className="mb-1.5 text-[10px] font-semibold uppercase tracking-wide text-fd-muted-foreground/80">
Sources
</p>
<div className="flex flex-wrap gap-1.5">
{sources.map((source) =>
source === "and many others" ? (
<span
key={source}
className="px-0.5 py-0.5 text-[10px] font-medium leading-4 text-fd-muted-foreground/85"
>
{source}
</span>
) : (
<span
key={source}
className="rounded border border-fd-border bg-fd-card/75 px-1.5 py-0.5 text-[10px] font-medium leading-4 text-fd-muted-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]"
>
{source}
</span>
),
)}
</div>
</div>
);
}
function CodeBox({ children }: { children: ReactNode }) {
return (
<div className="max-w-full min-w-0 overflow-x-auto rounded-md border border-fd-border bg-[#0c1417] p-3 font-mono text-[11px] leading-5 text-cyan-50 shadow-sm">

View file

@ -1,6 +1,6 @@
---
title: Introduction
description: How KTX gives analytics agents trusted context for warehouse work.
description: What KTX is, how it works, and where to start.
---
import { ProductMechanics } from "@/components/product-mechanics";
@ -23,29 +23,39 @@ import { ProductMechanics } from "@/components/product-mechanics";
Make analytics context usable by agents
</h1>
<p className="mt-4 max-w-2xl text-lg text-fd-muted-foreground" style={{ lineHeight: '1.7' }}>
{'KTX turns warehouse metadata, semantic definitions, and business knowledge into reviewable project files that agents can use while planning, querying, and updating analytics work.'}
{'KTX turns warehouse metadata, semantic definitions, BI usage, and team knowledge into local files and runtime tools that database agents can trust.'}
</p>
</div>
</div>
## Why KTX
- Schemas show columns, not business rules.
- Agents need trusted metrics, joins, filters, caveats, and provenance.
- KTX captures that context before agents write SQL, docs, or semantic edits.
## What KTX creates
| Path | What it gives agents |
|------|----------------------|
| `semantic-layer/` | Measures, dimensions, joins, grain, filters, segments |
| `wiki/` | Business definitions, caveats, policies, analyst notes |
| `raw-sources/` | Extracted metadata, scan output, relationship evidence |
| `.ktx/` | Local indexes, embeddings, setup state, runtime data |
<ProductMechanics />
## What agents can do with KTX
KTX is built for analytics engineers and data teams who want data agents to
work on real analytics systems, not just generate one-off SQL.
Use it when agents need to:
## Use it for
- **Generate SQL** from approved measures, dimensions, joins, and filters
- **Explain provenance** with wiki context and warehouse evidence
- **Repair context** through reviewable YAML and Markdown diffs
- **Work alongside** dbt, LookML, MetricFlow, Looker, Metabase, and warehouses
KTX works with SQLite, PostgreSQL, Snowflake, BigQuery, ClickHouse, MySQL, and
SQL Server.
Databases: SQLite, PostgreSQL, Snowflake, BigQuery, ClickHouse, MySQL, SQL
Server.
## Read next
## Start here
<Cards>
<Card title="Quickstart" href="/docs/getting-started/quickstart">
@ -60,16 +70,7 @@ SQL Server.
<Card title="CLI Reference" href="/docs/cli-reference/ktx-setup">
Complete flag and subcommand reference for every KTX command.
</Card>
<Card title="AI Resources" href="/docs/ai-resources">
Machine-readable docs and agent-facing setup notes.
</Card>
</Cards>
## Agent usage notes
| Agent task | Read next |
|------------|-----------|
| Discover machine-readable docs | [AI Resources](/docs/ai-resources) |
| Learn how a coding assistant should approach KTX | [Agent Quickstart](/docs/ai-resources/agent-quickstart) |
| Set up a new KTX project | [Quickstart](/docs/getting-started/quickstart) |
| Explain what problem KTX solves | [The Context Layer](/docs/concepts/the-context-layer) |
| Scan a database and ingest metadata | [Building Context](/docs/guides/building-context) |
| Edit semantic sources or wiki pages | [Writing Context](/docs/guides/writing-context) |
| Look up exact command flags | [CLI Reference](/docs/cli-reference/ktx-setup) |

View file

@ -10,7 +10,7 @@ async function readDocsFile(path) {
return readFile(join(docsSiteDir, path), "utf8");
}
test("docs introduction shows the ingestion and runtime mechanics early", async () => {
test("docs introduction frames the concept before showing product mechanics", async () => {
const introduction = await readDocsFile(
"content/docs/getting-started/introduction.mdx",
);
@ -22,14 +22,24 @@ test("docs introduction shows the ingestion and runtime mechanics early", async
assert.match(introduction, /<ProductMechanics\s*\/>/);
const heroIndex = introduction.indexOf("Make analytics context");
const whyIndex = introduction.indexOf("## Why KTX");
const createsIndex = introduction.indexOf("## What KTX creates");
const mechanicsIndex = introduction.indexOf("<ProductMechanics />");
const useCaseIndex = introduction.indexOf("## What agents can do with KTX");
const useCaseIndex = introduction.indexOf("## Use it for");
const heroSource = introduction.slice(0, mechanicsIndex);
assert.ok(heroIndex >= 0, "introduction should include the custom hero");
assert.ok(
mechanicsIndex > heroIndex,
"mechanics component should appear after the hero",
whyIndex > heroIndex,
"problem framing should appear after the hero",
);
assert.ok(
createsIndex > whyIndex,
"artifact summary should appear after problem framing",
);
assert.ok(
mechanicsIndex > createsIndex,
"mechanics component should appear after the artifact summary",
);
assert.ok(
mechanicsIndex < useCaseIndex,
@ -45,7 +55,9 @@ test("product mechanics component covers source-specific context and SQL expansi
const component = await readDocsFile("components/product-mechanics.tsx");
for (const expectedText of [
"A semantic compiler for analytics agents",
"How KTX works",
"Build context from source evidence",
"Run agent requests through the model",
"Ingestion",
"Runtime",
"wiki/",
@ -53,10 +65,23 @@ test("product mechanics component covers source-specific context and SQL expansi
"raw-sources/",
".ktx/",
"sl_refs",
"Database structure",
"BI and usage evidence",
"Semantic modeling",
"Company documentation",
"Notion pages",
"Sources",
"KTX transforms evidence",
"KTX builds the model",
"Outputs KTX writes",
"Postgres",
"Snowflake",
"BigQuery",
"and many others",
"Metabase",
"query history",
"Looker",
"MetricFlow",
"LookML",
"extract evidence",
"reconcile entities",
"validate references",
@ -74,12 +99,27 @@ test("product mechanics component covers source-specific context and SQL expansi
);
}
assert.doesNotMatch(component, /Product mechanics/);
assert.doesNotMatch(component, /A semantic compiler for analytics agents/);
assert.doesNotMatch(component, /KTX does more than retrieve Markdown/);
assert.doesNotMatch(component, /Plain Markdown \+ RAG/);
assert.doesNotMatch(component, /comparisonRows/);
assert.doesNotMatch(component, /ComparisonTable/);
assert.doesNotMatch(component, /Not just retrieval/);
assert.doesNotMatch(component, /KTX works in two moments/);
assert.doesNotMatch(component, /name: "Metabase and query history"/);
assert.doesNotMatch(component, /name: "dbt, MetricFlow, LookML"/);
assert.doesNotMatch(component, /query history/);
assert.doesNotMatch(component, /analyst notes/);
assert.doesNotMatch(component, /ClickHouse/);
assert.doesNotMatch(component, /MySQL/);
assert.doesNotMatch(component, /SQL Server/);
assert.doesNotMatch(component, /SQLite/);
assert.doesNotMatch(
component,
/\/ktx\/brand\/(?:postgresql|snowflake|bigquery|clickhouse|mysql|sqlserver|sqlite|metabase|dbt|looker|notion)\.svg/,
);
assert.doesNotMatch(component, /<img/);
assert.doesNotMatch(component, /w-\[calc\(100vw/);
assert.doesNotMatch(component, /xl:grid-cols-2/);
assert.doesNotMatch(component, /lg:grid-cols-\[[^\]]*_2rem_/);