mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The sign-in callback, initiate and logout pages, authz, auto, the
connectors page, base, the blog index and its three posts, and the Go
module page wrap their copy: server pages with <T>, client pages with
t(), and copy held in data with phrase(). Figures in the posts' prose
are values; product names, code and IAM's own codes stay as written.
Models says its two sentences whole ("{n}+ models", "every model on
the gateway"); the noun prop no caller passed is gone.
143 lines
6.3 KiB
TypeScript
143 lines
6.3 KiB
TypeScript
'use client'
|
||
|
||
import { ArrowRight, Clock, Cog, Eye, GitBranch, Plug, Shield, Zap } from 'lucide-react'
|
||
import { phrase } from '@hanzo/i18n'
|
||
import { useI18n } from '@hanzo/i18n/react'
|
||
import { Box } from '@hanzo/ui'
|
||
import { Band, Head } from '@/components/marketing/band'
|
||
import { OSSRevenueBanner } from '@/components/oss/OSSRevenueBanner'
|
||
import { ProductLanding } from '@/components/product/ProductLanding'
|
||
import { ProductFooter } from '@/components/products/ProductFooter'
|
||
import { Line } from '@hanzo/ui/marketing'
|
||
|
||
/**
|
||
* Hanzo Auto, through the ONE product kit.
|
||
*
|
||
* auto, dashboards and flow scored 93–100% identical on their className sets —
|
||
* the same hero, stat row, six-card grid and call to action three more times.
|
||
* See LLM.md, "Tailwind is NOT gone".
|
||
*
|
||
* EVERY WORD IS THE ONE THAT WAS HERE.
|
||
*
|
||
* The connector list is auto's alone, so it rides `children` — which is what
|
||
* that prop is for, and why it is not a fourteenth field on the shared props.
|
||
* It is a GRID of twelve names, not `chips`'s wrapped row of pills: twelve reads
|
||
* as a catalog, and a catalog is ruled. What it now shares with its ten
|
||
* neighbours is the FRAME — `Band` states the rule, the rhythm, the gutter and
|
||
* the measure, and `Head` the centred heading, so this section stopped stating
|
||
* `py-24 sm:px-6 lg:px-8` and `max-w-7xl` a second time three inches below the
|
||
* kit that already says them.
|
||
*/
|
||
|
||
/** The names, once. Twelve near-identical tiles were twelve copies of one tile. */
|
||
const CONNECTORS = ['Slack', 'GitHub', 'Notion', 'Gmail', 'Stripe', 'HubSpot', 'Jira', 'Linear', 'Discord', 'Airtable', 'Google Sheets', 'Postgres']
|
||
|
||
/**
|
||
* One name in a ruled cell. Not `Leaf` and not `Chip`: it neither opens nor
|
||
* hovers, and its corner is the 12px card rung rather than a pill's.
|
||
*/
|
||
const TILE = {
|
||
render: 'div',
|
||
display: 'block',
|
||
p: 12,
|
||
borderWidth: 1,
|
||
borderColor: 'var(--neutral-800)',
|
||
rounded: 'var(--radius-lg)',
|
||
bg: 'color-mix(in oklab, var(--neutral-900) 40%, transparent)',
|
||
text: 'center',
|
||
fontSize: '$2',
|
||
lineHeight: 'calc(1.25 / 0.875)',
|
||
fontWeight: '500',
|
||
color: 'var(--foreground)',
|
||
} as const
|
||
|
||
export default function HanzoAutoPage() {
|
||
const { t } = useI18n()
|
||
return (
|
||
<>
|
||
<ProductLanding
|
||
badge={"auto.hanzo.ai"}
|
||
badgeIcon={Cog}
|
||
title={"Hanzo Auto"}
|
||
tagline={phrase("Workflow automation in one binary")}
|
||
lede={phrase("Draw a workflow, connect the apps it touches, and fire it from a webhook or a schedule. The whole thing is one Go process: the editor, the connector catalog, the database and the durable executor are compiled in. There is no Node at runtime, no reverse proxy to configure, and no Postgres to run beside it. One image, one port, one thing to restart.")}
|
||
ctas={[
|
||
{ label: phrase("Open Auto"), href: "https://auto.hanzo.ai", icon: ArrowRight },
|
||
{ label: phrase("Documentation"), href: "https://docs.hanzo.ai/docs/cli/auto" },
|
||
]}
|
||
what={{
|
||
title: phrase("A run that survives the restart"),
|
||
sub: phrase("Most of what makes automation hard is what happens on step seven of nine when the process dies."),
|
||
pillars: [
|
||
{
|
||
icon: Clock,
|
||
title: phrase("Durable execution"),
|
||
body: phrase("A run is a record, not a goroutine. Step state is written down as it goes, so a crash, a deploy or a rescheduled pod resumes where it stopped rather than starting over or losing the run."),
|
||
},
|
||
{
|
||
icon: Plug,
|
||
title: phrase("The catalog is in the binary"),
|
||
body: phrase("GET /v1/pieces lists the connectors this build has. No plugin registry to reach at boot, so the version you deployed is the version that runs, offline and forever."),
|
||
},
|
||
{
|
||
icon: Zap,
|
||
title: phrase("Triggers"),
|
||
body: phrase("POST to a trigger and a run starts. Or start one by hand against /v1/runs. Either way it is the same run object with the same history."),
|
||
},
|
||
{
|
||
icon: Eye,
|
||
title: phrase("Watch it live"),
|
||
body: phrase("The editor is React Flow, embedded in the binary, and it follows a run over a server-sent event stream — so the canvas you drew is the canvas you watch execute."),
|
||
},
|
||
{
|
||
icon: GitBranch,
|
||
title: phrase("Draft, then publish"),
|
||
body: phrase("Edit a flow freely; nothing changes for callers until you publish. What triggers fire is a published version, so editing in the afternoon does not change what runs overnight."),
|
||
},
|
||
{
|
||
icon: Shield,
|
||
title: phrase("Connections, not pasted keys"),
|
||
body: phrase("A connection is a named credential the flow refers to. It is encrypted at rest through Hanzo KMS, and who may touch it is Hanzo IAM's answer, not a second login here."),
|
||
},
|
||
],
|
||
}}
|
||
stats={{
|
||
items: [
|
||
{ value: "Go", label: phrase("One process") },
|
||
{ value: "SQLite", label: phrase("Per replica") },
|
||
{ value: "/v1", label: phrase("Flows and runs") },
|
||
{ value: "Apache", label: phrase("Self-hosted") },
|
||
],
|
||
}}
|
||
finalCta={{
|
||
title: phrase("Or run it yourself"),
|
||
sub: phrase("One container, one port, a SQLite file for state. Nothing else to stand up first."),
|
||
buttons: [
|
||
{ label: phrase("Open Auto"), href: "https://auto.hanzo.ai", icon: ArrowRight },
|
||
{ label: phrase("View on GitHub"), href: "https://github.com/hanzoai" },
|
||
],
|
||
}}
|
||
>
|
||
<Band>
|
||
<Head title={t('Some of what it connects')} />
|
||
<Box
|
||
display="grid"
|
||
gridTemplateColumns="repeat(3, minmax(0, 1fr))"
|
||
gap={16}
|
||
$md={{ gridTemplateColumns: 'repeat(4, minmax(0, 1fr))' }}
|
||
$lg={{ gridTemplateColumns: 'repeat(6, minmax(0, 1fr))' }}
|
||
>
|
||
{CONNECTORS.map((name) => (
|
||
<Line key={name} {...TILE}>
|
||
{name}
|
||
</Line>
|
||
))}
|
||
</Box>
|
||
</Band>
|
||
<OSSRevenueBanner />
|
||
</ProductLanding>
|
||
<ProductFooter slug={"auto"} name={"Auto"} />
|
||
</>
|
||
)
|
||
}
|