mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
import { Text, YStack } from '@/components/ui'
|
|
import { Grid } from '@hanzo/ui/grid'
|
|
import { Band, Head, Action, Actions, Split } from './band'
|
|
import { Term, type Line } from '@/components/frame/Term'
|
|
|
|
/**
|
|
* And it runs on your machine, too: the same cloud, booted on the reader's own
|
|
* laptop in about the time it takes to read this sentence. The landing leads
|
|
* with the cloud and the builder; this is the one slide for the local half.
|
|
*
|
|
* Of everything this site claims, this is the one a developer can falsify in
|
|
* two minutes, which is exactly why it earns the space. Every line of the
|
|
* transcript below is what the CLI actually prints — `hanzo up`'s own strings
|
|
* (`creating the k3s checkpoint…`, `k3s is up — API at https://127.0.0.1:6443`,
|
|
* the `export KUBECONFIG` hint) come from crates/cli `src/commands/up.rs`, and
|
|
* the timings are the published medians. Nothing here is dressed up; a
|
|
* transcript that does not match the tool is a lie a reader discovers in the
|
|
* first minute, and it costs more than the section is worth.
|
|
*/
|
|
const SESSION: Line[] = [
|
|
{ kind: 'run', text: 'curl -fsSL https://hanzo.sh | sh' },
|
|
{ kind: 'note', text: 'hanzo → /usr/local/bin/hanzo' },
|
|
{ kind: 'gap' },
|
|
|
|
{ kind: 'run', text: 'hanzo up' },
|
|
{ kind: 'out', text: '→ creating the k3s checkpoint (downloads k3s once)…' },
|
|
{
|
|
kind: 'ok',
|
|
text: '✓ k3s is up — API at https://127.0.0.1:6443',
|
|
time: '7.1s',
|
|
},
|
|
{ kind: 'note', text: 'export KUBECONFIG=~/.kube/hanzo.yaml' },
|
|
{ kind: 'gap' },
|
|
|
|
{ kind: 'run', text: 'kubectl get nodes' },
|
|
{ kind: 'out', text: 'NAME STATUS ROLES AGE' },
|
|
{ kind: 'out', text: 'hanzo Ready control-plane,master 4s' },
|
|
{ kind: 'gap' },
|
|
|
|
{ kind: 'run', text: 'hanzo vm run --allow-net alpine' },
|
|
{ kind: 'ok', text: '✓ booted', time: '0.30s' },
|
|
]
|
|
|
|
/**
|
|
* The three numbers under the transcript.
|
|
*
|
|
* A measurement and what it measures — no icon, no card, no border. The figure
|
|
* is already the picture; these are its caption, and giving them chrome of
|
|
* their own would make the section argue with itself.
|
|
*/
|
|
const FACTS: { value: string; what: string }[] = [
|
|
{
|
|
value: '0.30s',
|
|
what: 'to boot the microVM — the same on Apple silicon, Ryzen and GB10.',
|
|
},
|
|
{
|
|
value: '7s',
|
|
what: 'from cold to a Ready node, every platform we ship.',
|
|
},
|
|
{
|
|
value: 'No Docker',
|
|
what: 'and no daemon, no VM manager, and no cloud account to open.',
|
|
},
|
|
]
|
|
|
|
export function Boot() {
|
|
return (
|
|
<Band id="boot" wide>
|
|
<Split
|
|
says={
|
|
<>
|
|
<Head
|
|
eyebrow="Local"
|
|
title="Runs on your machine, too."
|
|
lede="One command boots the same cloud on your laptop: a Kubernetes control plane in a microVM, ready in seconds."
|
|
/>
|
|
|
|
{/* `Fit`, not a count and not a breakpoint: three across where there is
|
|
room, wrapping down on a phone, with no media query to keep in step. */}
|
|
<Grid columns={{ min: 150, max: 3 }} gap={20} mt={28}>
|
|
{FACTS.map((f) => (
|
|
<YStack key={f.value}>
|
|
<Text display="block" fontFamily="$mono" fontSize="$7" fontWeight="500" letterSpacing="$7" color="$ink">
|
|
{f.value}
|
|
</Text>
|
|
<Text render="p" display="block" mt={6} fontSize="$2" lineHeight="1.3203rem" color="var(--muted-foreground)">
|
|
{f.what}
|
|
</Text>
|
|
</YStack>
|
|
))}
|
|
</Grid>
|
|
|
|
<Actions top={28}>
|
|
<Action href="/cli" filled>
|
|
Read the CLI docs
|
|
</Action>
|
|
<Action href="https://docs.hanzo.ai/docs/quickstart">Run it locally</Action>
|
|
</Actions>
|
|
</>
|
|
}
|
|
>
|
|
<Term title="~/work" lines={SESSION} />
|
|
</Split>
|
|
</Band>
|
|
)
|
|
}
|