From ca6289fab43cdf35e10e108110040e3ac427465e Mon Sep 17 00:00:00 2001 From: gongzhiyong Date: Thu, 30 Apr 2026 00:38:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=9D=99=E6=80=81=E5=AE=98=E7=BD=91?= =?UTF-8?q?=E4=B8=8E=20Docker=20Compose=20=E6=9C=AC=E5=9C=B0=E9=83=A8?= =?UTF-8?q?=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - website: 单页落地(愿景、架构、路径、团队范式、生命周期) - nginx:alpine 镜像与 docker-compose(端口 8888) Made-with: Cursor --- docker-compose.yml | 8 + website/.dockerignore | 2 + website/Dockerfile | 3 + website/css/styles.css | 466 +++++++++++++++++++++++++++++++++++++++++ website/index.html | 316 ++++++++++++++++++++++++++++ website/js/main.js | 16 ++ website/nginx.conf | 13 ++ 7 files changed, 824 insertions(+) create mode 100644 docker-compose.yml create mode 100644 website/.dockerignore create mode 100644 website/Dockerfile create mode 100644 website/css/styles.css create mode 100644 website/index.html create mode 100644 website/js/main.js create mode 100644 website/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..69d9219 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +services: + heicode-www: + build: + context: ./website + dockerfile: Dockerfile + ports: + - "8888:80" + restart: unless-stopped diff --git a/website/.dockerignore b/website/.dockerignore new file mode 100644 index 0000000..4a246ec --- /dev/null +++ b/website/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +.dockerignore diff --git a/website/Dockerfile b/website/Dockerfile new file mode 100644 index 0000000..ff02415 --- /dev/null +++ b/website/Dockerfile @@ -0,0 +1,3 @@ +FROM nginx:alpine +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY . /usr/share/nginx/html diff --git a/website/css/styles.css b/website/css/styles.css new file mode 100644 index 0000000..e39506f --- /dev/null +++ b/website/css/styles.css @@ -0,0 +1,466 @@ +:root { + --bg-deep: #0b0f14; + --bg-card: #121920; + --bg-elevated: #1a222d; + --border: rgba(120, 190, 200, 0.15); + --text: #e8eef4; + --muted: #8fa3b8; + --accent: #3dd6c6; + --accent-dim: #2a9d8f; + --warn: #f4a261; + --font-sans: "DM Sans", "PingFang SC", "Microsoft YaHei", sans-serif; + --font-mono: "JetBrains Mono", ui-monospace, monospace; + --radius: 12px; + --shadow: 0 24px 80px rgba(0, 0, 0, 0.45); +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + font-family: var(--font-sans); + background: var(--bg-deep); + color: var(--text); + line-height: 1.65; + font-size: 16px; +} + +a { + color: var(--accent); + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + +.wrap { + width: min(1120px, 92vw); + margin-inline: auto; +} + +header.site-header { + position: sticky; + top: 0; + z-index: 40; + backdrop-filter: blur(12px); + background: rgba(11, 15, 20, 0.85); + border-bottom: 1px solid var(--border); +} + +.nav-inner { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.85rem 0; + gap: 1rem; +} + +.logo { + font-weight: 700; + letter-spacing: -0.03em; + font-size: 1.25rem; + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--text); +} +.logo-mark { + width: 32px; + height: 32px; + border-radius: 8px; + background: linear-gradient(135deg, var(--accent), #2563eb); + display: grid; + place-items: center; + font-size: 0.75rem; + font-weight: 800; + color: #041018; +} + +nav ul { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 1.25rem; + align-items: center; +} + +nav a { + color: var(--muted); + font-size: 0.95rem; +} +nav a:hover { + color: var(--text); +} + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.4rem; + padding: 0.55rem 1.1rem; + border-radius: 999px; + font-weight: 600; + font-size: 0.92rem; + border: 1px solid transparent; + cursor: pointer; + transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s; +} +.btn:active { + transform: scale(0.98); +} + +.btn-primary { + background: linear-gradient(135deg, var(--accent), var(--accent-dim)); + color: #041018; +} +.btn-primary:hover { + filter: brightness(1.08); + text-decoration: none; +} + +.btn-ghost { + background: transparent; + border-color: var(--border); + color: var(--text); +} +.btn-ghost:hover { + border-color: var(--accent); + text-decoration: none; +} + +.hero { + padding: 4.5rem 0 3.5rem; + position: relative; + overflow: hidden; +} + +.hero::before { + content: ""; + position: absolute; + inset: -40% -20% auto; + height: 70%; + background: radial-gradient(ellipse at 50% 0%, rgba(61, 214, 198, 0.18), transparent 55%); + pointer-events: none; +} + +.hero-grid { + display: grid; + gap: 2.5rem; + align-items: center; +} +@media (min-width: 900px) { + .hero-grid { + grid-template-columns: 1.1fr 0.9fr; + } +} + +.hero h1 { + font-size: clamp(2rem, 4.5vw, 3rem); + line-height: 1.15; + letter-spacing: -0.04em; + margin: 0 0 1rem; +} + +.lead { + color: var(--muted); + font-size: 1.08rem; + max-width: 36rem; + margin: 0 0 1.5rem; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; +} + +.badge-row { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.25rem; +} + +.badge { + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + padding: 0.35rem 0.65rem; + border-radius: 6px; + background: var(--bg-elevated); + border: 1px solid var(--border); + color: var(--muted); +} + +.hero-panel { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.25rem; + box-shadow: var(--shadow); + font-family: var(--font-mono); + font-size: 0.78rem; + line-height: 1.5; + color: #b8c9d9; +} +.hero-panel .comment { + color: #5c6f82; +} +.hero-panel .key { + color: var(--accent); +} +.hero-panel .str { + color: #a5d6ff; +} + +section { + padding: 3.5rem 0; +} + +section:nth-child(even) { + background: linear-gradient(180deg, rgba(26, 34, 45, 0.35), transparent); +} + +.section-title { + font-size: 1.75rem; + margin: 0 0 0.5rem; + letter-spacing: -0.03em; +} +.section-desc { + color: var(--muted); + max-width: 42rem; + margin: 0 0 2rem; +} + +.grid-3 { + display: grid; + gap: 1.25rem; +} +@media (min-width: 700px) { + .grid-3 { + grid-template-columns: repeat(3, 1fr); + } +} + +.card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.35rem; + height: 100%; +} +.card h3 { + margin: 0 0 0.6rem; + font-size: 1.1rem; +} +.card p { + margin: 0; + color: var(--muted); + font-size: 0.95rem; +} + +.arch-diagram { + display: grid; + gap: 1rem; +} +@media (min-width: 800px) { + .arch-diagram { + grid-template-columns: repeat(3, 1fr); + align-items: stretch; + } +} + +.arch-box { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1.25rem; + background: var(--bg-elevated); +} +.arch-box h4 { + margin: 0 0 0.5rem; + font-size: 0.95rem; + color: var(--accent); +} +.arch-box ul { + margin: 0; + padding-left: 1.1rem; + color: var(--muted); + font-size: 0.9rem; +} + +.flow { + display: grid; + gap: 1rem; + counter-reset: step; +} +@media (min-width: 750px) { + .flow { + grid-template-columns: repeat(5, 1fr); + } +} + +.flow-step { + position: relative; + padding: 1rem; + border-radius: var(--radius); + border: 1px dashed var(--border); + background: rgba(18, 25, 32, 0.6); +} +.flow-step::before { + counter-increment: step; + content: counter(step); + position: absolute; + top: -10px; + left: 12px; + background: var(--bg-deep); + border: 1px solid var(--accent); + color: var(--accent); + width: 26px; + height: 26px; + border-radius: 999px; + font-size: 0.75rem; + font-weight: 700; + display: grid; + place-items: center; +} +.flow-step strong { + display: block; + margin-bottom: 0.35rem; +} +.flow-step span { + font-size: 0.85rem; + color: var(--muted); +} + +.team-grid { + display: grid; + gap: 1.5rem; +} +@media (min-width: 800px) { + .team-grid { + grid-template-columns: 1fr 1fr; + } +} + +.team-block { + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + background: var(--bg-card); +} +.team-head { + padding: 1rem 1.25rem; + border-bottom: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: baseline; + flex-wrap: wrap; + gap: 0.5rem; +} +.team-head h3 { + margin: 0; + font-size: 1.15rem; +} +.team-meta { + font-size: 0.85rem; + color: var(--warn); + font-weight: 600; +} +.team-body { + padding: 1rem 1.25rem 1.25rem; +} +.team-body table { + width: 100%; + border-collapse: collapse; + font-size: 0.82rem; +} +.team-body th, +.team-body td { + text-align: left; + padding: 0.45rem 0.35rem; + border-bottom: 1px solid var(--border); + vertical-align: top; +} +.team-body th { + color: var(--muted); + font-weight: 500; + width: 22%; +} +.role-tag { + font-family: var(--font-mono); + font-size: 0.75rem; + color: var(--accent); +} + +.lifecycle { + display: grid; + gap: 0.75rem; +} +@media (min-width: 720px) { + .lifecycle { + grid-template-columns: repeat(3, 1fr); + } +} +.lifecycle .card small { + display: block; + color: var(--accent); + font-weight: 600; + margin-bottom: 0.35rem; + font-size: 0.8rem; +} + +.cta { + text-align: center; + padding: 4rem 0 5rem; +} +.cta-box { + border: 1px solid var(--border); + border-radius: calc(var(--radius) + 4px); + padding: 2.5rem 1.5rem; + background: linear-gradient(145deg, rgba(61, 214, 198, 0.08), rgba(37, 99, 235, 0.06)); +} +.cta h2 { + margin: 0 0 0.75rem; + font-size: 1.6rem; +} +.cta p { + color: var(--muted); + margin: 0 0 1.25rem; +} + +footer.site-footer { + border-top: 1px solid var(--border); + padding: 2rem 0 2.5rem; + color: var(--muted); + font-size: 0.88rem; +} +.footer-row { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 1rem; +} + +.skip-link { + position: absolute; + left: -9999px; +} +.skip-link:focus { + left: 1rem; + top: 1rem; + z-index: 100; + padding: 0.5rem 1rem; + background: var(--accent); + color: #041018; +} diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..9201001 --- /dev/null +++ b/website/index.html @@ -0,0 +1,316 @@ + + + + + + + Heicode · 智能体驱动的团队交付 + + + + + + + + + + +
+
+
+
+
+ New API + CLI · Desktop + Agnet + 多云交付 +
+

从想法到上线
用智能体团队完成整条交付链

+

+ Heicode 将改造后的大模型网关、类 Claude Code 的终端与桌面客户端,以及 + Agnet 平台上的子智能体团队连成一体:需求、实现、测试、部署与运维在同一范式下可审计、可扩展。 +

+ +
+ +
+
+ +
+
+

我们在解决什么问题

+

+ 单一编码插件只能加速「写代码」;Heicode 面向团队与组织,把自动化扩展到规格、协作、质量门禁、多云发布与运维迭代,并形成可追溯的产物(文档、日志、多智能体沟通)。 +

+
+
+

统一账号与模型策略

+

登录改造后的 New API 控制台,管理令牌、配额与渠道策略,终端与桌面客户端与服务端对齐同一身份。

+
+
+

可编排的子智能体团队

+

在 Agnet 一键部署瀑布或敏捷模板(5~9 / 3~8 子 Agnet),按角色分工覆盖从需求到上线的闸门。

+
+
+

全生命周期与可审计

+

Git 与云资源在策略下自动化;交付物与版本、发布关联,支持多成员协作下的沟通与开发日志沉淀。

+
+
+
+
+ +
+
+

逻辑架构

+

+ 浏览器与 CLI/Desktop 共用网关能力;Agnet 承载子智能体编排;外部系统(Git、公有云、CI/CD)在最小权限原则下接入。 +

+
+
+

体验层

+
    +
  • 官网 / 文档
  • +
  • New API 控制台
  • +
  • CLI · Desktop(Tauri)
  • +
+
+
+

平台层

+
    +
  • 改造后的 New API(账号 · 计费 · 中继)
  • +
  • 本地服务 / API 路由(cc-haha)
  • +
+
+
+

执行与基础设施

+
    +
  • Agnet:子智能体团队 · 有状态实例
  • +
  • Git · GCP · AWS · Azure
  • +
+
+
+
+
+ +
+
+

核心用户路径

+

从访问官网到持续迭代,目标体验拆成可落地的五步。

+
+
+ 发现 + 访问官网,了解范式与下载入口。 +
+
+ 登录控制台 + 进入改造后的 New API,查看令牌与策略。 +
+
+ 安装客户端 + 下载 CLI / Desktop,登录后与网关对齐会话。 +
+
+ 部署子团队 + 在 Agnet 一键拉起瀑布或敏捷子 Agnet 队列。 +
+
+ 交付与迭代 + 开发、测试、发布、观测与计划任务更新。 +
+
+
+
+ +
+
+

团队范式(子 Agnet)

+

+ 规模设计兼顾协调成本:瀑布强调阶段闸门(最小 5、最大 9);敏捷强调迭代闭环(最小 3、最大 8)。详细职责见仓库内愿景文档。 +

+
+
+
+

瀑布模式

+ 最小 5 · 最大 9 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
代号角色
WF-BA业务/需求分析师
WF-ARC解决方案架构师
WF-DEV软件工程师(最小配置)
WF-QA测试工程师
WF-REL发布与运维工程师
+

+ 最大配置扩展为 PM、前后端分立、安全、文档等专岗 — 详见文档第五节。 +

+
+
+
+
+

敏捷模式

+ 最小 3 · 最大 8 +
+
+ + + + + + + + + + + + + + + + + + + + + +
代号角色
AG-PO产品负责人
AG-DEV软件工程师
AG-QA测试工程师
+

+ 最大配置增加 SM、Tech Lead、双轨 Dev、UX、SRE — 超出 8 人等价容量时拆第二支 Squad。 +

+
+
+
+
+
+ +
+
+

软件生命周期

+

同一范式覆盖规格、实现、验证、发布、运维与迭代;敏感操作由策略与人机审批约束。

+
+
+ 规格 · 协作 +

需求与设计

+

PRD、接口契约、风险与非功能需求落档,与子 Agnet 角色对齐。

+
+
+ 构建 · 质量 +

实现与测试

+

代码、评审、自动化测试与质量门禁,绑定分支与 CI。

+
+
+ 发布 · 运维 +

部署与迭代

+

多云发布、可观测、回滚与 Runbook;计划任务驱动持续迭代。

+
+
+
+
+ +
+
+

文档与参考

+

+ 仓库内维护完整愿景与角色表;外部可参考 Claude Code 生态实践(如 oh-my-claudecode)。Agnet 与 New API 以实际部署环境为准。 +

+
+
+

愿景范式(仓库)

+

docs/vision-heicode-full-stack-agentic-dev.md

+
+ +
+

本地预览本站

+

在项目根目录执行 docker compose up --build,浏览器访问站点端口。

+
+
+
+
+ +
+
+
+

把「想法」连接到你的平台现实

+

+ Heicode 正在把网关、客户端与 Agnet 团队揉合成一条可落地的交付链。下一步:冻结账号契约、打通一键部署与状态回传。 +

+ 返回架构 +
+
+
+
+ + + + + + diff --git a/website/js/main.js b/website/js/main.js new file mode 100644 index 0000000..3fcae28 --- /dev/null +++ b/website/js/main.js @@ -0,0 +1,16 @@ +(() => { + const year = document.querySelector("[data-year]"); + if (year) year.textContent = String(new Date().getFullYear()); + + document.querySelectorAll('a[href^="#"]').forEach((anchor) => { + anchor.addEventListener("click", (e) => { + const id = anchor.getAttribute("href"); + if (!id || id === "#") return; + const el = document.querySelector(id); + if (el) { + e.preventDefault(); + el.scrollIntoView({ behavior: "smooth", block: "start" }); + } + }); + }); +})(); diff --git a/website/nginx.conf b/website/nginx.conf new file mode 100644 index 0000000..8b22c87 --- /dev/null +++ b/website/nginx.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + gzip on; + gzip_types text/css application/javascript application/json text/plain; +}