mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
docs: clarify getting started introduction (#120)
This commit is contained in:
parent
b318671d31
commit
c7e6b5001d
3 changed files with 167 additions and 69 deletions
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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) |
|
||||
|
|
|
|||
|
|
@ -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_/);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue