155 lines
6.6 KiB
TypeScript
155 lines
6.6 KiB
TypeScript
import { Bot, CreditCard, KeyRound, Layers, Monitor, Terminal } from "lucide-react";
|
|
import type { Lang } from "@/app/page";
|
|
|
|
const icons = [Terminal, Monitor, Bot, CreditCard, KeyRound, Layers];
|
|
|
|
const copy = {
|
|
en: {
|
|
eyebrow: "Product surfaces",
|
|
title: "Users operate Heicode. The underlying systems stay in their lanes.",
|
|
description:
|
|
"The client is the primary experience and Manager is the auxiliary console. CodeGW, the vault, and the Agnet platform are not exposed as ordinary user backends.",
|
|
products: [
|
|
{
|
|
name: "Heicode Client",
|
|
description:
|
|
"The primary user experience. Describe ideas, continue development, review Agnet execution feedback, and approve risky operations before production deploys, secret access, or cloud changes.",
|
|
features: ["Idea input", "Task progress", "Execution feedback", "Risk approval"],
|
|
},
|
|
{
|
|
name: "Heicode Manager",
|
|
description:
|
|
"The browser-side control console for account safety, client downloads, resource binding, Agnet deployment, task status, balance, and audit.",
|
|
features: ["Resource binding", "Deploy Agnets", "Model balance", "Audit logs"],
|
|
},
|
|
{
|
|
name: "Agnet Platform",
|
|
description:
|
|
"The AI development-team execution layer. It runs Product, Frontend, Backend, Reviewer, Ops, and other sub Agnets on AKS, then reports state and events back.",
|
|
features: ["Role teams", "Continuous execution", "SK calls", "State callback"],
|
|
},
|
|
{
|
|
name: "CodeGW",
|
|
description:
|
|
"The internal model gateway and billing foundation. Heicode only exposes the models, balance, quota, usage, and call logs ordinary users need.",
|
|
features: ["Model gateway", "Balance quota", "Call logs", "No admin exposure"],
|
|
},
|
|
{
|
|
name: "Secret Vault",
|
|
description:
|
|
"Credential custody backed by OpenBao. Long-lived secrets only enter the vault; sub Agnets receive short-lived, least-privilege credentials.",
|
|
features: ["secret_ref", "Short-lived creds", "Rotate and revoke", "Audit trail"],
|
|
},
|
|
{
|
|
name: "Resource Context",
|
|
description:
|
|
"Git, SK, documents, cloud accounts, and cloud resources become Resource Bindings and Grants that can be authorized, revoked, and audited.",
|
|
features: ["Git", "SK", "Project docs", "Cloud resources"],
|
|
},
|
|
],
|
|
},
|
|
zh: {
|
|
eyebrow: "Product surfaces",
|
|
title: "用户只操作 Heicode,底层能力各归其位",
|
|
description:
|
|
"客户端是主体验,Manager 是辅助控制台;CodeGW、密钥保管器和 Agnet 平台不作为普通用户后台。",
|
|
products: [
|
|
{
|
|
name: "Heicode 客户端",
|
|
description:
|
|
"用户主体验。输入想法、继续开发、查看 Agnet 执行反馈,并在生产部署、密钥访问、云操作前完成高危审批。",
|
|
features: ["想法输入", "任务推进", "执行反馈", "高危审批"],
|
|
},
|
|
{
|
|
name: "Heicode Manager",
|
|
description:
|
|
"浏览器辅助控制台。负责账号安全、客户端下载、资源绑定、Agnet 部署、任务状态、余额和审计。",
|
|
features: ["资源绑定", "部署 Agnet", "模型余额", "审计日志"],
|
|
},
|
|
{
|
|
name: "Agnet 平台",
|
|
description:
|
|
"AI 开发团队执行层。在 AKS 上运行 Product、Frontend、Backend、Reviewer、Ops 等子 Agnet,并回传状态和事件。",
|
|
features: ["角色团队", "持续执行", "SK 调用", "状态回传"],
|
|
},
|
|
{
|
|
name: "CodeGW",
|
|
description:
|
|
"内部模型网关和计费底座。Heicode 只展示普通用户需要的模型、余额、额度、用量和调用日志。",
|
|
features: ["模型网关", "余额额度", "调用日志", "不开放后台"],
|
|
},
|
|
{
|
|
name: "密钥保管器",
|
|
description:
|
|
"OpenBao 实现的凭证托管服务。长期密钥只进入密钥保管器,子 Agnet 只拿短期、最小权限凭证。",
|
|
features: ["secret_ref", "短期凭证", "轮换撤销", "审计记录"],
|
|
},
|
|
{
|
|
name: "资源上下文",
|
|
description:
|
|
"把 Git、SK、文档、云账号和云资源变成可授权、可撤销、可审计的 Resource Binding 和 Grant。",
|
|
features: ["Git", "SK", "项目文档", "云资源"],
|
|
},
|
|
],
|
|
},
|
|
} satisfies Record<Lang, {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
products: Array<{ name: string; description: string; features: string[] }>;
|
|
}>;
|
|
|
|
export function Products({ lang }: { lang: Lang }) {
|
|
const t = copy[lang];
|
|
|
|
return (
|
|
<section id="products" className="py-20 sm:py-28">
|
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="mx-auto max-w-2xl text-center">
|
|
<p className="text-sm font-bold tracking-widest text-primary uppercase">
|
|
{t.eyebrow}
|
|
</p>
|
|
<h2 className="mt-4 text-3xl font-black tracking-tight sm:text-5xl">
|
|
{t.title}
|
|
</h2>
|
|
<p className="mt-4 text-muted-foreground">
|
|
{t.description}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-14 grid gap-5 md:grid-cols-2 xl:grid-cols-3">
|
|
{t.products.map((product, index) => {
|
|
const Icon = icons[index];
|
|
return (
|
|
<div
|
|
key={product.name}
|
|
className="group relative overflow-hidden rounded-[1.7rem] border border-border bg-card/65 p-7 shadow-sm transition-all hover:-translate-y-1 hover:border-primary/40 hover:shadow-xl"
|
|
>
|
|
<div className="absolute -right-10 -top-10 h-28 w-28 rounded-full bg-primary/5 transition-colors group-hover:bg-primary/10" />
|
|
<div className="mb-6 flex h-12 w-12 items-center justify-center rounded-2xl bg-secondary text-primary">
|
|
<Icon className="h-6 w-6" />
|
|
</div>
|
|
|
|
<h3 className="text-xl font-semibold">{product.name}</h3>
|
|
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
|
|
{product.description}
|
|
</p>
|
|
|
|
<div className="mt-6 flex flex-wrap gap-2">
|
|
{product.features.map((feature) => (
|
|
<span
|
|
key={feature}
|
|
className="rounded-full bg-secondary px-3 py-1 text-xs text-muted-foreground"
|
|
>
|
|
{feature}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|