mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
Calculator, captable, careers, cloud, compare, contact and contact-sales, customers, dashboards, dataroom, datastore, dev, download, enso, enterprise, extension, family, integrations, investors, kai, learn, legal and their components say their words through t() in client code, <T> in server components and phrase() where copy is held as data; one sentence is one key, figures and links its arguments. Rebased on main: in every conflict main's file stands (its copy, layout and styling) and only the wrapping is added back, including copy main added since. Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
219 lines
8.8 KiB
TypeScript
219 lines
8.8 KiB
TypeScript
'use client'
|
||
|
||
import type { ReactNode } from 'react'
|
||
import { SiteFooter, SiteHeader } from '@/components/home/shell'
|
||
import { Hero } from '@/components/family/Hero'
|
||
import { Read } from '@/components/family/Read'
|
||
import Closing from '@/components/marketing/Closing'
|
||
import { Band, Card, Head } from '@/components/marketing/band'
|
||
import { Rise } from '@/components/marketing/rise'
|
||
import { Term, type Line } from '@/components/frame/Term'
|
||
import { Box, Text, XStack, YStack } from '@/components/ui'
|
||
import { Faq } from '@/components/ui/faq'
|
||
import { Grid } from '@hanzo/ui/grid'
|
||
import { More } from '@hanzo/ui/marketing'
|
||
import { AgentPrompt } from '@/components/product/AgentPrompt'
|
||
import { product } from '@/lib/product'
|
||
import { phrase } from '@hanzo/i18n'
|
||
import { useI18n } from '@hanzo/i18n/react'
|
||
|
||
const REPO = 'https://github.com/hanzoai/kata'
|
||
const DOCS = 'https://docs.hanzo.ai/docs/coding'
|
||
|
||
const TERMINAL_LINES: Line[] = [
|
||
{ kind: 'run', text: 'kata run --suite tests/unit' },
|
||
{ kind: 'note', text: '12 passed · 1 failed (test_token_expiry)' },
|
||
{ kind: 'gap' },
|
||
{ kind: 'run', text: 'kata triage' },
|
||
{ kind: 'note', text: 'Kai decision: patch · confidence: 0.96 · root cause: off-by-one jitter' },
|
||
{ kind: 'gap' },
|
||
{ kind: 'run', text: 'kata repair --model enso-ultra' },
|
||
{ kind: 'note', text: 'synthesized AST edit in auth/tokens.py · re-running test suite...' },
|
||
{ kind: 'gap' },
|
||
{ kind: 'ok', text: '13 passed · 0 failed · 100% green verification' },
|
||
]
|
||
|
||
const PIPELINE_STEPS = [
|
||
{
|
||
step: phrase('01 · Observe'),
|
||
title: phrase('Catch the failure'),
|
||
desc: phrase('Reads the stack trace, exit code and test log from pytest, cargo test, vitest or go test.'),
|
||
},
|
||
{
|
||
step: phrase('02 · Decide'),
|
||
title: phrase('Choose what to do'),
|
||
desc: phrase('Kai scores retry, patch, roll back or hand to a person, as probabilities, and writes no text.'),
|
||
},
|
||
{
|
||
step: phrase('03 · Write'),
|
||
title: phrase('Write the fix'),
|
||
desc: phrase('Enso picks the model that writes the edit, weighing quality, latency and budget.'),
|
||
},
|
||
{
|
||
step: phrase('04 · Verify'),
|
||
title: phrase('Prove it'),
|
||
desc: phrase('The candidate diff runs in an isolated microVM sandbox. Only a change whose whole suite passes lands.'),
|
||
},
|
||
]
|
||
|
||
const KATA_FEATURES = [
|
||
{
|
||
title: phrase('Test repair, end to end'),
|
||
desc: phrase('Finds regressions and flaky tests, traces each to its root cause, writes the smallest diff and checks that the suite passes.'),
|
||
},
|
||
{
|
||
title: phrase('Triage by Kai'),
|
||
desc: phrase('No prose to parse: Kai returns a probability for each action, patch, roll back, retry or approve.'),
|
||
},
|
||
{
|
||
title: phrase('Models picked by Enso'),
|
||
desc: phrase('Each attempt runs on enso-auto, enso-flash or enso-ultra, trading cost against accuracy.'),
|
||
},
|
||
{
|
||
title: phrase('Runs in your pipeline'),
|
||
desc: phrase('In GitHub Actions, GitLab CI or a pre-push hook in your terminal.'),
|
||
},
|
||
]
|
||
|
||
const QUESTIONS = [
|
||
{
|
||
question: phrase('How does Kata differ from Hanzo Dev and Gen?'),
|
||
answer: phrase('Dev is the coding agent that plans and writes whole features. Gen runs any coding agent on Hanzo’s tools and models. Kata repairs failing tests in CI: it triages each failure and lands a fix only when the suite passes.'),
|
||
},
|
||
{
|
||
question: phrase('Which test frameworks does Kata support?'),
|
||
answer: phrase('Kata natively supports pytest, vitest, jest, cargo test, go test, and custom test runners emitting standard TAP or JUnit XML output.'),
|
||
},
|
||
{
|
||
question: phrase('Where can I find the open-source examples and recipes?'),
|
||
answer: phrase('The open-source repository is at github.com/hanzoai/kata with runnable examples in Python, TypeScript, Go, Rust, and cURL, along with a standalone Rust recipes crate.'),
|
||
},
|
||
{
|
||
question: phrase('How do I authenticate with Hanzo Cloud?'),
|
||
answer: phrase('Log in once with `hanzo auth login` or export `HANZO_API_KEY` from platform.hanzo.ai/keys.'),
|
||
},
|
||
]
|
||
|
||
export default function KataLanding() {
|
||
const { t } = useI18n()
|
||
return (
|
||
<>
|
||
<SiteHeader />
|
||
|
||
<Box render="main" bg="$background" $platform-web={{ color: 'var(--foreground)' }}>
|
||
<Hero
|
||
chip={t('Hanzo Kata · Test repair')}
|
||
title={
|
||
<>
|
||
{t('Test. Repair. Verify.')}
|
||
<br />
|
||
{t('Autonomous loop.')}
|
||
</>
|
||
}
|
||
lede={t('Kata keeps your tests green. It triages a failing CI run, finds the regression, writes the fix and runs the suite again before anything lands.')}
|
||
primary={{ label: t('Get API key'), href: 'https://platform.hanzo.ai/keys' }}
|
||
action={{ label: t('Explore GitHub examples →'), href: REPO }}
|
||
more={{ label: t('Read the docs →'), href: DOCS }}
|
||
figure={<Term title="terminal" lines={TERMINAL_LINES} />}
|
||
/>
|
||
|
||
{/* 4-Step Closed Loop Pipeline */}
|
||
<Band id="pipeline" measure={1180}>
|
||
<Head
|
||
eyebrow={t('The loop')}
|
||
title={t('From a failing test to a verified fix.')}
|
||
lede={t('Kata never submits speculative code: Kai triages every failure, Enso writes the fix, and your own test suite decides whether it lands.')}
|
||
loud
|
||
/>
|
||
<Grid columns={{ min: 260, max: 4 }} gap={16} mt="$6">
|
||
{PIPELINE_STEPS.map((s, i) => (
|
||
<Rise key={s.step} beat={i}>
|
||
<Card display="flex" flexDirection="column" gap="$2" p="$5" height="100%" borderColor="var(--border)" bg="$panel">
|
||
<Text fontFamily="$mono" fontSize="$1" lineHeight="$1" color="var(--primary)" textTransform="uppercase">
|
||
{t(s.step)}
|
||
</Text>
|
||
<Text render="h3" fontSize="$4" lineHeight="$4" fontWeight="600" color="$ink">
|
||
{t(s.title)}
|
||
</Text>
|
||
<Text fontSize="$2" lineHeight="$3" color="var(--text-secondary)">
|
||
{t(s.desc)}
|
||
</Text>
|
||
</Card>
|
||
</Rise>
|
||
))}
|
||
</Grid>
|
||
</Band>
|
||
|
||
{/* Feature Grid */}
|
||
<Band id="features" measure={1180}>
|
||
<Head
|
||
eyebrow={t('Capabilities')}
|
||
title={t('Built for the pipeline.')}
|
||
lede={t('Test repair, triage and the choice of model, in the CI you already run.')}
|
||
loud
|
||
/>
|
||
<Grid columns={{ min: 280, max: 2 }} gap={16} mt="$6">
|
||
{KATA_FEATURES.map((f, i) => (
|
||
<Rise key={f.title} beat={i}>
|
||
<Card display="flex" flexDirection="column" gap="$3" p="$6" height="100%" borderColor="var(--border)">
|
||
<Text render="h3" fontSize="$5" lineHeight="$5" fontWeight="600" color="$ink">
|
||
{t(f.title)}
|
||
</Text>
|
||
<Text fontSize="$3" lineHeight="$3" color="var(--text-secondary)">
|
||
{t(f.desc)}
|
||
</Text>
|
||
</Card>
|
||
</Rise>
|
||
))}
|
||
</Grid>
|
||
</Band>
|
||
|
||
|
||
{/* FAQ Section */}
|
||
<Band measure={768}>
|
||
<Head eyebrow={t('Questions')} title={t('Asked plainly.')} />
|
||
<Faq items={QUESTIONS.map((q) => ({ question: t(q.question), answer: t(q.answer) }))} />
|
||
</Band>
|
||
|
||
{/* Read Section */}
|
||
<Read
|
||
eyebrow={t('Read')}
|
||
title={t('The agent, the loop, the documentation.')}
|
||
lede={t('Explore the source code, recipes, and documentation.')}
|
||
groups={[
|
||
{
|
||
label: 'Kata',
|
||
links: [
|
||
{ href: REPO, label: 'hanzoai/kata →', note: t('GitHub Repository.') },
|
||
{ href: `${REPO}/tree/main/examples`, label: t('Multi-Language SDKs →') },
|
||
{ href: `${REPO}/tree/main/recipes`, label: t('Rust Recipes Crate →') },
|
||
],
|
||
},
|
||
{
|
||
label: t('Agent Systems'),
|
||
links: [
|
||
{ href: '/dev', label: 'Hanzo Dev →', note: t('Our coding agent.') },
|
||
{ href: '/gen', label: 'Hanzo Gen →', note: t('Universal harness.') },
|
||
{ href: '/kai', label: 'Kai →', note: t('Decision engine.') },
|
||
],
|
||
},
|
||
{
|
||
label: t('Models'),
|
||
links: [
|
||
{ href: '/enso', label: 'Enso →', note: t('Model router.') },
|
||
{ href: '/zen', label: 'Zen →', note: t('Open weights.') },
|
||
{ href: '/models', label: t('Every model →') },
|
||
],
|
||
},
|
||
]}
|
||
/>
|
||
|
||
{product('kata') && <AgentPrompt product={product('kata')!} />}
|
||
<Closing title={t('Keep your test suites green.')} secondary={{ label: t('Explore repair recipes'), href: 'https://github.com/hanzoai/kata/tree/main/recipes' }} />
|
||
</Box>
|
||
|
||
<SiteFooter />
|
||
</>
|
||
)
|
||
}
|