From 7e2b328e3c1b508bf3f17e9ed3b03b2e9d3d515b Mon Sep 17 00:00:00 2001 From: Jiayuan Date: Wed, 1 Apr 2026 05:47:40 +0800 Subject: [PATCH] feat(web): add i18n support to landing page with Simplified Chinese MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add dictionary-based i18n system (en/zh) with React Context provider - Extract all hardcoded text from landing components into translation dictionaries - Auto-detect browser language, persist preference in localStorage - Add language switcher (EN/中文) to footer - Add Noto Serif SC font for Chinese serif headings - Rewrite about page Chinese copy with user-provided translation --- apps/web/app/(landing)/about/page.tsx | 66 ++-- apps/web/app/(landing)/changelog/page.tsx | 71 +--- apps/web/app/(landing)/layout.tsx | 13 +- .../landing/components/faq-section.tsx | 44 +-- .../landing/components/features-section.tsx | 116 +----- .../components/how-it-works-section.tsx | 48 +-- .../landing/components/landing-footer.tsx | 62 ++-- .../landing/components/landing-header.tsx | 11 +- .../landing/components/landing-hero.tsx | 25 +- .../components/open-source-section.tsx | 42 +-- apps/web/features/landing/i18n/context.tsx | 51 +++ apps/web/features/landing/i18n/en.ts | 333 ++++++++++++++++++ apps/web/features/landing/i18n/index.ts | 3 + apps/web/features/landing/i18n/types.ts | 95 +++++ apps/web/features/landing/i18n/zh.ts | 333 ++++++++++++++++++ 15 files changed, 962 insertions(+), 351 deletions(-) create mode 100644 apps/web/features/landing/i18n/context.tsx create mode 100644 apps/web/features/landing/i18n/en.ts create mode 100644 apps/web/features/landing/i18n/index.ts create mode 100644 apps/web/features/landing/i18n/types.ts create mode 100644 apps/web/features/landing/i18n/zh.ts diff --git a/apps/web/app/(landing)/about/page.tsx b/apps/web/app/(landing)/about/page.tsx index 5c2d8773..5d842239 100644 --- a/apps/web/app/(landing)/about/page.tsx +++ b/apps/web/app/(landing)/about/page.tsx @@ -1,56 +1,46 @@ +"use client"; + import Link from "next/link"; import { LandingHeader } from "@/features/landing/components/landing-header"; import { LandingFooter } from "@/features/landing/components/landing-footer"; import { GitHubMark, githubUrl } from "@/features/landing/components/shared"; +import { useLocale } from "@/features/landing/i18n"; export default function AboutPage() { + const { t } = useLocale(); + const n = t.about.nameLine; + return ( <>

- About Multica + {t.about.title}

- Multica — Multiplexed - Information and{" "} - Computing{" "} - Agent. -

-

- The name is a nod to Multics, the pioneering operating system of - the 1960s that introduced time-sharing — letting multiple users - share a single machine as if each had it to themselves. Unix was - born as a deliberate simplification of Multics: one user, one task, - one elegant philosophy. -

-

- We think the same inflection is happening again. For decades, - software teams have been single-threaded — one engineer, one task, - one context switch at a time. AI agents change that equation. - Multica brings time-sharing back, but for an era where the - “users” multiplexing the system are both humans and - autonomous agents. -

-

- In Multica, agents are first-class teammates. They get assigned - issues, report progress, raise blockers, and ship code — just like - their human colleagues. The assignee picker, the activity timeline, - the task lifecycle, and the runtime infrastructure are all built - around this idea from day one. -

-

- Like Multics before it, the bet is on multiplexing: a small team - shouldn't feel small. With the right system, two engineers and - a fleet of agents can move like twenty. -

-

- The platform is fully open source and self-hostable. Your data - stays on your infrastructure. Inspect every line, extend the API, - bring your own LLM providers, and contribute back to the community. + {n.prefix} + + {n.mul} + + {n.tiplexed} + + {n.i} + + {n.nformationAnd} + + {n.c} + + {n.omputing} + + {n.a} + + {n.gent}

+ {t.about.paragraphs.map((p, i) => ( +

{p}

+ ))}
@@ -61,7 +51,7 @@ export default function AboutPage() { className="inline-flex items-center gap-2.5 rounded-[12px] bg-[#0a0d12] px-5 py-3 text-[14px] font-semibold text-white transition-colors hover:bg-[#0a0d12]/88" > - View on GitHub + {t.about.cta}
diff --git a/apps/web/app/(landing)/changelog/page.tsx b/apps/web/app/(landing)/changelog/page.tsx index 25c9eade..e1351687 100644 --- a/apps/web/app/(landing)/changelog/page.tsx +++ b/apps/web/app/(landing)/changelog/page.tsx @@ -1,81 +1,26 @@ +"use client"; + import { LandingHeader } from "@/features/landing/components/landing-header"; import { LandingFooter } from "@/features/landing/components/landing-footer"; - -const changelog = [ - { - version: "0.1.3", - date: "2026-03-31", - title: "Agent Intelligence", - changes: [ - "Trigger agents via @mention in comments", - "Stream live agent output to issue detail page", - "Rich text editor — mentions, link paste, emoji reactions, collapsible threads", - "File upload with S3 + CloudFront signed URLs and attachment tracking", - "Agent-driven repo checkout with bare clone cache for task isolation", - "Batch operations for issue list view", - "Daemon authentication and security hardening", - ], - }, - { - version: "0.1.2", - date: "2026-03-28", - title: "Collaboration", - changes: [ - "Email verification login and browser-based CLI auth", - "Multi-workspace daemon with hot-reload", - "Runtime dashboard with usage charts and activity heatmaps", - "Subscriber-driven notification model replacing hardcoded triggers", - "Unified activity timeline with threaded comment replies", - "Kanban board redesign with drag sorting, filters, and display settings", - "Human-readable issue identifiers (e.g. JIA-1)", - "Skill import from ClawHub and Skills.sh", - ], - }, - { - version: "0.1.1", - date: "2026-03-25", - title: "Core Platform", - changes: [ - "Multi-workspace switching and creation", - "Agent management UI with skills, tools, and triggers", - "Unified agent SDK supporting Claude Code and Codex backends", - "Comment CRUD with real-time WebSocket updates", - "Task service layer and daemon REST protocol", - "Event bus with workspace-scoped WebSocket isolation", - "Inbox notifications with unread badge and archive", - "CLI with cobra subcommands for workspace and issue management", - ], - }, - { - version: "0.1.0", - date: "2026-03-22", - title: "Foundation", - changes: [ - "Go backend with REST API, JWT auth, and real-time WebSocket", - "Next.js frontend with Linear-inspired UI", - "Issues with board and list views and drag-and-drop kanban", - "Agents, Inbox, and Settings pages", - "One-click setup, migration CLI, and seed tool", - "Comprehensive test suite — Go unit/integration, Vitest, Playwright E2E", - ], - }, -]; +import { useLocale } from "@/features/landing/i18n"; export default function ChangelogPage() { + const { t } = useLocale(); + return ( <>

- Changelog + {t.changelog.title}

- New updates and improvements to Multica. + {t.changelog.subtitle}

- {changelog.map((release) => ( + {t.changelog.entries.map((release) => (
diff --git a/apps/web/app/(landing)/layout.tsx b/apps/web/app/(landing)/layout.tsx index b5119cad..035f0e45 100644 --- a/apps/web/app/(landing)/layout.tsx +++ b/apps/web/app/(landing)/layout.tsx @@ -1,4 +1,5 @@ -import { Instrument_Serif } from "next/font/google"; +import { Instrument_Serif, Noto_Serif_SC } from "next/font/google"; +import { LocaleProvider } from "@/features/landing/i18n"; const instrumentSerif = Instrument_Serif({ subsets: ["latin"], @@ -6,14 +7,20 @@ const instrumentSerif = Instrument_Serif({ variable: "--font-serif", }); +const notoSerifSC = Noto_Serif_SC({ + subsets: ["latin"], + weight: "400", + variable: "--font-serif-zh", +}); + export default function LandingLayout({ children, }: { children: React.ReactNode; }) { return ( -
- {children} +
+ {children}
); } diff --git a/apps/web/features/landing/components/faq-section.tsx b/apps/web/features/landing/components/faq-section.tsx index ef303715..e32aed38 100644 --- a/apps/web/features/landing/components/faq-section.tsx +++ b/apps/web/features/landing/components/faq-section.tsx @@ -2,42 +2,10 @@ import { useState } from "react"; import { cn } from "@/lib/utils"; - -const faqs = [ - { - question: "What coding agents does Multica support?", - answer: - "Multica currently supports Claude Code and OpenAI Codex out of the box. The daemon auto-detects whichever CLIs you have installed. More backends are on the roadmap — and since it's open source, you can add your own.", - }, - { - question: "Do I need to self-host, or is there a cloud version?", - answer: - "Both. You can self-host Multica on your own infrastructure with Docker Compose or Kubernetes, or use our hosted cloud version. Your data, your choice.", - }, - { - question: - "How is this different from just using Claude Code or Codex directly?", - answer: - "Coding agents are great at executing. Multica adds the management layer: task queues, team coordination, skill reuse, runtime monitoring, and a unified view of what every agent is doing. Think of it as the project manager for your agents.", - }, - { - question: "Can agents work on long-running tasks autonomously?", - answer: - "Yes. Multica manages the full task lifecycle — enqueue, claim, execute, complete or fail. Agents report blockers proactively and stream progress in real time. You can check in whenever you want or let them run overnight.", - }, - { - question: "Is my code safe? Where does agent execution happen?", - answer: - "Agent execution happens on your machine (local daemon) or your own cloud infrastructure. Code never passes through Multica servers. The platform only coordinates task state and broadcasts events.", - }, - { - question: "How many agents can I run?", - answer: - "As many as your hardware supports. Each agent has configurable concurrency limits, and you can connect multiple machines as runtimes. There are no artificial caps in the open source version.", - }, -]; +import { useLocale } from "../i18n"; export function FAQSection() { + const { t } = useLocale(); const [openIndex, setOpenIndex] = useState(null); return ( @@ -45,16 +13,16 @@ export function FAQSection() {

- FAQ + {t.faq.label}

- Questions & answers. + {t.faq.headline}

- {faqs.map((faq, i) => ( -
+ {t.faq.items.map((faq, i) => ( +
+ ))} +
{/* Giant logo */} diff --git a/apps/web/features/landing/components/landing-header.tsx b/apps/web/features/landing/components/landing-header.tsx index 30394634..0a9f4960 100644 --- a/apps/web/features/landing/components/landing-header.tsx +++ b/apps/web/features/landing/components/landing-header.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { MulticaIcon } from "@/components/multica-icon"; import { cn } from "@/lib/utils"; +import { useLocale } from "../i18n"; import { GitHubMark, githubUrl, headerButtonClassName } from "./shared"; export function LandingHeader({ @@ -10,11 +11,15 @@ export function LandingHeader({ }: { variant?: "dark" | "light"; }) { + const { t } = useLocale(); + return (
@@ -44,13 +49,13 @@ export function LandingHeader({ className={headerButtonClassName("ghost", variant)} > - GitHub + {t.header.github} - Log in + {t.header.login}
diff --git a/apps/web/features/landing/components/landing-hero.tsx b/apps/web/features/landing/components/landing-hero.tsx index bac891ee..5e607e98 100644 --- a/apps/web/features/landing/components/landing-hero.tsx +++ b/apps/web/features/landing/components/landing-hero.tsx @@ -1,5 +1,8 @@ +"use client"; + import Image from "next/image"; import Link from "next/link"; +import { useLocale } from "../i18n"; import { ClaudeCodeLogo, CodexLogo, @@ -9,6 +12,8 @@ import { } from "./shared"; export function LandingHero() { + const { t } = useLocale(); + return (
@@ -20,20 +25,18 @@ export function LandingHero() { >

- Your next 10 hires + {t.hero.headlineLine1}
- won't be human. + {t.hero.headlineLine2}

- Multica is an open-source platform that turns coding agents into - real teammates. Assign tasks, track progress, compound skills — - manage your human + agent workforce in one place. + {t.hero.subheading}

- Start free trial + {t.hero.cta}
- Works with + + {t.hero.worksWith} +
@@ -62,7 +67,7 @@ export function LandingHero() {
- +
@@ -84,14 +89,14 @@ function LandingBackdrop() { ); } -function ProductImage() { +function ProductImage({ alt }: { alt: string }) { return (
{/* eslint-disable-next-line @next/next/no-img-element */} Multica board view — issues managed by humans and agents
diff --git a/apps/web/features/landing/components/open-source-section.tsx b/apps/web/features/landing/components/open-source-section.tsx index be45a1de..809aff35 100644 --- a/apps/web/features/landing/components/open-source-section.tsx +++ b/apps/web/features/landing/components/open-source-section.tsx @@ -1,30 +1,12 @@ +"use client"; + import Link from "next/link"; +import { useLocale } from "../i18n"; import { GitHubMark, githubUrl } from "./shared"; -const openSourceHighlights = [ - { - title: "Self-host anywhere", - description: - "Run Multica on your own infrastructure. Docker Compose, single binary, or Kubernetes — your data never leaves your network.", - }, - { - title: "No vendor lock-in", - description: - "Bring your own LLM provider, swap agent backends, extend the API. You own the stack, top to bottom.", - }, - { - title: "Transparent by default", - description: - "Every line of code is auditable. See exactly how your agents make decisions, how tasks are routed, and where your data flows.", - }, - { - title: "Community-driven", - description: - "Built with the community, not just for it. Contribute skills, integrations, and agent backends that benefit everyone.", - }, -]; - export function OpenSourceSection() { + const { t } = useLocale(); + return (
@@ -32,17 +14,15 @@ export function OpenSourceSection() { {/* Left column — heading + CTA */}

- Open source + {t.openSource.label}

- Open source + {t.openSource.headlineLine1}
- for all. + {t.openSource.headlineLine2}

- Multica is fully open source. Inspect every line, self-host on - your own terms, and shape the future of human + agent - collaboration. + {t.openSource.description}

- Star on GitHub + {t.openSource.cta}
@@ -60,7 +40,7 @@ export function OpenSourceSection() { {/* Right column — highlight grid */}
- {openSourceHighlights.map((item) => ( + {t.openSource.highlights.map((item) => (

{item.title} diff --git a/apps/web/features/landing/i18n/context.tsx b/apps/web/features/landing/i18n/context.tsx new file mode 100644 index 00000000..54067723 --- /dev/null +++ b/apps/web/features/landing/i18n/context.tsx @@ -0,0 +1,51 @@ +"use client"; + +import { createContext, useContext, useState, useCallback } from "react"; +import { en } from "./en"; +import { zh } from "./zh"; +import type { LandingDict, Locale } from "./types"; + +const dictionaries: Record = { en, zh }; + +const STORAGE_KEY = "multica-locale"; + +function getInitialLocale(): Locale { + if (typeof window === "undefined") return "en"; + const stored = localStorage.getItem(STORAGE_KEY); + if (stored === "en" || stored === "zh") return stored; + // Detect from browser language + const lang = navigator.language; + if (lang.startsWith("zh")) return "zh"; + return "en"; +} + +type LocaleContextValue = { + locale: Locale; + t: LandingDict; + setLocale: (locale: Locale) => void; +}; + +const LocaleContext = createContext(null); + +export function LocaleProvider({ children }: { children: React.ReactNode }) { + const [locale, setLocaleState] = useState(getInitialLocale); + + const setLocale = useCallback((l: Locale) => { + setLocaleState(l); + localStorage.setItem(STORAGE_KEY, l); + }, []); + + return ( + + {children} + + ); +} + +export function useLocale() { + const ctx = useContext(LocaleContext); + if (!ctx) throw new Error("useLocale must be used within LocaleProvider"); + return ctx; +} diff --git a/apps/web/features/landing/i18n/en.ts b/apps/web/features/landing/i18n/en.ts new file mode 100644 index 00000000..dea7f131 --- /dev/null +++ b/apps/web/features/landing/i18n/en.ts @@ -0,0 +1,333 @@ +import { githubUrl } from "../components/shared"; +import type { LandingDict } from "./types"; + +export const en: LandingDict = { + header: { + github: "GitHub", + login: "Log in", + }, + + hero: { + headlineLine1: "Your next 10 hires", + headlineLine2: "won\u2019t be human.", + subheading: + "Multica is an open-source platform that turns coding agents into real teammates. Assign tasks, track progress, compound skills \u2014 manage your human + agent workforce in one place.", + cta: "Start free trial", + worksWith: "Works with", + imageAlt: "Multica board view \u2014 issues managed by humans and agents", + }, + + features: { + teammates: { + label: "TEAMMATES", + title: "Assign to an agent like you\u2019d assign to a colleague", + description: + "Agents aren\u2019t passive tools \u2014 they\u2019re active participants. They have profiles, report status, create issues, comment, and change status. Your activity feed shows humans and agents working side by side.", + cards: [ + { + title: "Agents in the assignee picker", + description: + "Humans and agents appear in the same dropdown. Assigning work to an agent is no different from assigning it to a colleague.", + }, + { + title: "Autonomous participation", + description: + "Agents create issues, leave comments, and update status on their own \u2014 not just when prompted.", + }, + { + title: "Unified activity timeline", + description: + "One feed for the whole team. Human and agent actions are interleaved, so you always know what happened and who did it.", + }, + ], + }, + autonomous: { + label: "AUTONOMOUS", + title: "Set it and forget it \u2014 agents work while you sleep", + description: + "Not just prompt-response. Full task lifecycle management: enqueue, claim, start, complete or fail. Agents report blockers proactively and you get real-time progress via WebSocket.", + cards: [ + { + title: "Complete task lifecycle", + description: + "Every task flows through enqueue \u2192 claim \u2192 start \u2192 complete/fail. No silent failures \u2014 every transition is tracked and broadcast.", + }, + { + title: "Proactive block reporting", + description: + "When an agent gets stuck, it raises a flag immediately. No more checking back hours later to find nothing happened.", + }, + { + title: "Real-time progress streaming", + description: + "WebSocket-powered live updates. Watch agents work in real time, or check in whenever you want \u2014 the timeline is always current.", + }, + ], + }, + skills: { + label: "SKILLS", + title: "Every solution becomes a reusable skill for the whole team", + description: + "Skills are reusable capability definitions \u2014 code, config, and context bundled together. Write a skill once, and every agent on your team can use it. Your skill library compounds over time.", + cards: [ + { + title: "Reusable skill definitions", + description: + "Package knowledge into skills that any agent can execute. Deploy to staging, write migrations, review PRs \u2014 all codified.", + }, + { + title: "Team-wide sharing", + description: + "One person\u2019s skill is every agent\u2019s skill. Build once, benefit everywhere across your team.", + }, + { + title: "Compound growth", + description: + "Day 1: you teach an agent to deploy. Day 30: every agent deploys, writes tests, and does code review. Your team\u2019s capabilities grow exponentially.", + }, + ], + }, + runtimes: { + label: "RUNTIMES", + title: "One dashboard for all your compute", + description: + "Local daemons and cloud runtimes, managed from a single panel. Real-time monitoring of online/offline status, usage charts, and activity heatmaps. Auto-detects local CLIs \u2014 plug in and go.", + cards: [ + { + title: "Unified runtime panel", + description: + "Local daemons and cloud runtimes in one view. No context switching between different management interfaces.", + }, + { + title: "Real-time monitoring", + description: + "Online/offline status, usage charts, and activity heatmaps. Know exactly what your compute is doing at any moment.", + }, + { + title: "Auto-detection & plug-and-play", + description: + "Multica detects available CLIs like Claude Code and Codex automatically. Connect a machine, and it\u2019s ready to work.", + }, + ], + }, + }, + + howItWorks: { + label: "Get started", + headlineMain: "Hire your first AI employee", + headlineFaded: "in the next hour.", + steps: [ + { + title: "Sign up & create your workspace", + description: + "Enter your email, verify with a code, and you\u2019re in. Your workspace is created automatically \u2014 no setup wizard, no configuration forms.", + }, + { + title: "Install the CLI & connect your machine", + description: + "Run multica login to authenticate, then multica daemon start. The daemon auto-detects Claude Code and Codex on your machine \u2014 plug in and go.", + }, + { + title: "Create your first agent", + description: + "Give it a name, write instructions, attach skills, and set triggers. Choose when it activates: on assignment, on comment, or on mention.", + }, + { + title: "Assign an issue and watch it work", + description: + "Pick your agent from the assignee dropdown \u2014 just like assigning to a teammate. The task is queued, claimed, and executed automatically. Watch progress in real time.", + }, + ], + cta: "Get started", + ctaGithub: "View on GitHub", + }, + + openSource: { + label: "Open source", + headlineLine1: "Open source", + headlineLine2: "for all.", + description: + "Multica is fully open source. Inspect every line, self-host on your own terms, and shape the future of human + agent collaboration.", + cta: "Star on GitHub", + highlights: [ + { + title: "Self-host anywhere", + description: + "Run Multica on your own infrastructure. Docker Compose, single binary, or Kubernetes \u2014 your data never leaves your network.", + }, + { + title: "No vendor lock-in", + description: + "Bring your own LLM provider, swap agent backends, extend the API. You own the stack, top to bottom.", + }, + { + title: "Transparent by default", + description: + "Every line of code is auditable. See exactly how your agents make decisions, how tasks are routed, and where your data flows.", + }, + { + title: "Community-driven", + description: + "Built with the community, not just for it. Contribute skills, integrations, and agent backends that benefit everyone.", + }, + ], + }, + + faq: { + label: "FAQ", + headline: "Questions & answers.", + items: [ + { + question: "What coding agents does Multica support?", + answer: + "Multica currently supports Claude Code and OpenAI Codex out of the box. The daemon auto-detects whichever CLIs you have installed. More backends are on the roadmap \u2014 and since it\u2019s open source, you can add your own.", + }, + { + question: "Do I need to self-host, or is there a cloud version?", + answer: + "Both. You can self-host Multica on your own infrastructure with Docker Compose or Kubernetes, or use our hosted cloud version. Your data, your choice.", + }, + { + question: + "How is this different from just using Claude Code or Codex directly?", + answer: + "Coding agents are great at executing. Multica adds the management layer: task queues, team coordination, skill reuse, runtime monitoring, and a unified view of what every agent is doing. Think of it as the project manager for your agents.", + }, + { + question: "Can agents work on long-running tasks autonomously?", + answer: + "Yes. Multica manages the full task lifecycle \u2014 enqueue, claim, execute, complete or fail. Agents report blockers proactively and stream progress in real time. You can check in whenever you want or let them run overnight.", + }, + { + question: "Is my code safe? Where does agent execution happen?", + answer: + "Agent execution happens on your machine (local daemon) or your own cloud infrastructure. Code never passes through Multica servers. The platform only coordinates task state and broadcasts events.", + }, + { + question: "How many agents can I run?", + answer: + "As many as your hardware supports. Each agent has configurable concurrency limits, and you can connect multiple machines as runtimes. There are no artificial caps in the open source version.", + }, + ], + }, + + footer: { + tagline: + "Project management for human + agent teams. Open source, self-hostable, built for the future of work.", + cta: "Get started", + groups: { + product: { + label: "Product", + links: [ + { label: "Features", href: "#features" }, + { label: "How it Works", href: "#how-it-works" }, + { label: "Changelog", href: "/changelog" }, + ], + }, + resources: { + label: "Resources", + links: [ + { label: "Documentation", href: githubUrl }, + { label: "API", href: githubUrl }, + { label: "Community", href: githubUrl }, + ], + }, + company: { + label: "Company", + links: [ + { label: "About", href: "/about" }, + { label: "Open Source", href: "#open-source" }, + { label: "GitHub", href: githubUrl }, + ], + }, + }, + copyright: "\u00a9 {year} Multica. All rights reserved.", + }, + + about: { + title: "About Multica", + nameLine: { + prefix: "Multica \u2014 ", + mul: "Mul", + tiplexed: "tiplexed ", + i: "I", + nformationAnd: "nformation and ", + c: "C", + omputing: "omputing ", + a: "A", + gent: "gent.", + }, + paragraphs: [ + "The name is a nod to Multics, the pioneering operating system of the 1960s that introduced time-sharing \u2014 letting multiple users share a single machine as if each had it to themselves. Unix was born as a deliberate simplification of Multics: one user, one task, one elegant philosophy.", + "We think the same inflection is happening again. For decades, software teams have been single-threaded \u2014 one engineer, one task, one context switch at a time. AI agents change that equation. Multica brings time-sharing back, but for an era where the \u201cusers\u201d multiplexing the system are both humans and autonomous agents.", + "In Multica, agents are first-class teammates. They get assigned issues, report progress, raise blockers, and ship code \u2014 just like their human colleagues. The assignee picker, the activity timeline, the task lifecycle, and the runtime infrastructure are all built around this idea from day one.", + "Like Multics before it, the bet is on multiplexing: a small team shouldn\u2019t feel small. With the right system, two engineers and a fleet of agents can move like twenty.", + "The platform is fully open source and self-hostable. Your data stays on your infrastructure. Inspect every line, extend the API, bring your own LLM providers, and contribute back to the community.", + ], + cta: "View on GitHub", + }, + + changelog: { + title: "Changelog", + subtitle: "New updates and improvements to Multica.", + entries: [ + { + version: "0.1.3", + date: "2026-03-31", + title: "Agent Intelligence", + changes: [ + "Trigger agents via @mention in comments", + "Stream live agent output to issue detail page", + "Rich text editor \u2014 mentions, link paste, emoji reactions, collapsible threads", + "File upload with S3 + CloudFront signed URLs and attachment tracking", + "Agent-driven repo checkout with bare clone cache for task isolation", + "Batch operations for issue list view", + "Daemon authentication and security hardening", + ], + }, + { + version: "0.1.2", + date: "2026-03-28", + title: "Collaboration", + changes: [ + "Email verification login and browser-based CLI auth", + "Multi-workspace daemon with hot-reload", + "Runtime dashboard with usage charts and activity heatmaps", + "Subscriber-driven notification model replacing hardcoded triggers", + "Unified activity timeline with threaded comment replies", + "Kanban board redesign with drag sorting, filters, and display settings", + "Human-readable issue identifiers (e.g. JIA-1)", + "Skill import from ClawHub and Skills.sh", + ], + }, + { + version: "0.1.1", + date: "2026-03-25", + title: "Core Platform", + changes: [ + "Multi-workspace switching and creation", + "Agent management UI with skills, tools, and triggers", + "Unified agent SDK supporting Claude Code and Codex backends", + "Comment CRUD with real-time WebSocket updates", + "Task service layer and daemon REST protocol", + "Event bus with workspace-scoped WebSocket isolation", + "Inbox notifications with unread badge and archive", + "CLI with cobra subcommands for workspace and issue management", + ], + }, + { + version: "0.1.0", + date: "2026-03-22", + title: "Foundation", + changes: [ + "Go backend with REST API, JWT auth, and real-time WebSocket", + "Next.js frontend with Linear-inspired UI", + "Issues with board and list views and drag-and-drop kanban", + "Agents, Inbox, and Settings pages", + "One-click setup, migration CLI, and seed tool", + "Comprehensive test suite \u2014 Go unit/integration, Vitest, Playwright E2E", + ], + }, + ], + }, +}; diff --git a/apps/web/features/landing/i18n/index.ts b/apps/web/features/landing/i18n/index.ts new file mode 100644 index 00000000..33e9d563 --- /dev/null +++ b/apps/web/features/landing/i18n/index.ts @@ -0,0 +1,3 @@ +export { LocaleProvider, useLocale } from "./context"; +export { locales, localeLabels } from "./types"; +export type { Locale, LandingDict } from "./types"; diff --git a/apps/web/features/landing/i18n/types.ts b/apps/web/features/landing/i18n/types.ts new file mode 100644 index 00000000..a0249780 --- /dev/null +++ b/apps/web/features/landing/i18n/types.ts @@ -0,0 +1,95 @@ +export type Locale = "en" | "zh"; + +export const locales: Locale[] = ["en", "zh"]; + +export const localeLabels: Record = { + en: "EN", + zh: "\u4e2d\u6587", +}; + +type FeatureSection = { + label: string; + title: string; + description: string; + cards: { title: string; description: string }[]; +}; + +type FooterGroup = { + label: string; + links: { label: string; href: string }[]; +}; + +export type LandingDict = { + header: { github: string; login: string }; + hero: { + headlineLine1: string; + headlineLine2: string; + subheading: string; + cta: string; + worksWith: string; + imageAlt: string; + }; + features: { + teammates: FeatureSection; + autonomous: FeatureSection; + skills: FeatureSection; + runtimes: FeatureSection; + }; + howItWorks: { + label: string; + headlineMain: string; + headlineFaded: string; + steps: { title: string; description: string }[]; + cta: string; + ctaGithub: string; + }; + openSource: { + label: string; + headlineLine1: string; + headlineLine2: string; + description: string; + cta: string; + highlights: { title: string; description: string }[]; + }; + faq: { + label: string; + headline: string; + items: { question: string; answer: string }[]; + }; + footer: { + tagline: string; + cta: string; + groups: { + product: FooterGroup; + resources: FooterGroup; + company: FooterGroup; + }; + copyright: string; + }; + about: { + title: string; + nameLine: { + prefix: string; + mul: string; + tiplexed: string; + i: string; + nformationAnd: string; + c: string; + omputing: string; + a: string; + gent: string; + }; + paragraphs: string[]; + cta: string; + }; + changelog: { + title: string; + subtitle: string; + entries: { + version: string; + date: string; + title: string; + changes: string[]; + }[]; + }; +}; diff --git a/apps/web/features/landing/i18n/zh.ts b/apps/web/features/landing/i18n/zh.ts new file mode 100644 index 00000000..914b3d0c --- /dev/null +++ b/apps/web/features/landing/i18n/zh.ts @@ -0,0 +1,333 @@ +import { githubUrl } from "../components/shared"; +import type { LandingDict } from "./types"; + +export const zh: LandingDict = { + header: { + github: "GitHub", + login: "\u767b\u5f55", + }, + + hero: { + headlineLine1: "\u4f60\u7684\u4e0b\u4e00\u6279\u5458\u5de5", + headlineLine2: "\u4e0d\u662f\u4eba\u7c7b\u3002", + subheading: + "Multica \u662f\u4e00\u4e2a\u5f00\u6e90\u5e73\u53f0\uff0c\u5c06\u7f16\u7801 Agent \u53d8\u6210\u771f\u6b63\u7684\u961f\u53cb\u3002\u5206\u914d\u4efb\u52a1\u3001\u8ddf\u8e2a\u8fdb\u5ea6\u3001\u79ef\u7d2f\u6280\u80fd\u2014\u2014\u5728\u4e00\u4e2a\u5730\u65b9\u7ba1\u7406\u4f60\u7684\u4eba\u7c7b + Agent \u56e2\u961f\u3002", + cta: "\u514d\u8d39\u5f00\u59cb", + worksWith: "\u652f\u6301", + imageAlt: "Multica \u770b\u677f\u89c6\u56fe\u2014\u2014\u4eba\u7c7b\u548c Agent \u534f\u540c\u7ba1\u7406\u4efb\u52a1", + }, + + features: { + teammates: { + label: "\u56e2\u961f\u534f\u4f5c", + title: "\u50cf\u5206\u914d\u7ed9\u540c\u4e8b\u4e00\u6837\u5206\u914d\u7ed9 Agent", + description: + "Agent \u4e0d\u662f\u88ab\u52a8\u5de5\u5177\u2014\u2014\u5b83\u4eec\u662f\u4e3b\u52a8\u53c2\u4e0e\u8005\u3002\u5b83\u4eec\u62e5\u6709\u4e2a\u4eba\u8d44\u6599\u3001\u62a5\u544a\u72b6\u6001\u3001\u521b\u5efa Issue\u3001\u53d1\u8868\u8bc4\u8bba\u3001\u66f4\u65b0\u72b6\u6001\u3002\u4f60\u7684\u6d3b\u52a8\u6d41\u5c55\u793a\u4eba\u7c7b\u548c Agent \u5e76\u80a9\u5de5\u4f5c\u3002", + cards: [ + { + title: "Agent \u51fa\u73b0\u5728\u6307\u6d3e\u4eba\u9009\u62e9\u5668\u4e2d", + description: + "\u4eba\u7c7b\u548c Agent \u51fa\u73b0\u5728\u540c\u4e00\u4e2a\u4e0b\u62c9\u83dc\u5355\u91cc\u3002\u628a\u4efb\u52a1\u5206\u914d\u7ed9 Agent \u548c\u5206\u914d\u7ed9\u540c\u4e8b\u6ca1\u6709\u4efb\u4f55\u533a\u522b\u3002", + }, + { + title: "\u81ea\u4e3b\u53c2\u4e0e", + description: + "Agent \u4e3b\u52a8\u521b\u5efa Issue\u3001\u53d1\u8868\u8bc4\u8bba\u3001\u66f4\u65b0\u72b6\u6001\u2014\u2014\u800c\u4e0d\u662f\u53ea\u5728\u88ab\u63d0\u793a\u65f6\u624d\u884c\u52a8\u3002", + }, + { + title: "\u7edf\u4e00\u7684\u6d3b\u52a8\u65f6\u95f4\u7ebf", + description: + "\u6574\u4e2a\u56e2\u961f\u5171\u7528\u4e00\u4e2a\u6d3b\u52a8\u6d41\u3002\u4eba\u7c7b\u548c Agent \u7684\u64cd\u4f5c\u4ea4\u66ff\u5c55\u793a\uff0c\u4f60\u59cb\u7ec8\u77e5\u9053\u53d1\u751f\u4e86\u4ec0\u4e48\u3001\u662f\u8c01\u505a\u7684\u3002", + }, + ], + }, + autonomous: { + label: "\u81ea\u4e3b\u6267\u884c", + title: "\u8bbe\u7f6e\u540e\u65e0\u9700\u7ba1\u7406\u2014\u2014Agent \u5728\u4f60\u7761\u89c9\u65f6\u5de5\u4f5c", + description: + "\u4e0d\u53ea\u662f\u63d0\u793a-\u54cd\u5e94\u3002\u5b8c\u6574\u7684\u4efb\u52a1\u751f\u547d\u5468\u671f\u7ba1\u7406\uff1a\u5165\u961f\u3001\u9886\u53d6\u3001\u542f\u52a8\u3001\u5b8c\u6210\u6216\u5931\u8d25\u3002Agent \u4e3b\u52a8\u62a5\u544a\u963b\u585e\uff0c\u4f60\u901a\u8fc7 WebSocket \u83b7\u53d6\u5b9e\u65f6\u8fdb\u5ea6\u3002", + cards: [ + { + title: "\u5b8c\u6574\u7684\u4efb\u52a1\u751f\u547d\u5468\u671f", + description: + "\u6bcf\u4e2a\u4efb\u52a1\u7ecf\u5386\u5165\u961f \u2192 \u9886\u53d6 \u2192 \u542f\u52a8 \u2192 \u5b8c\u6210/\u5931\u8d25\u3002\u6ca1\u6709\u65e0\u58f0\u5931\u8d25\u2014\u2014\u6bcf\u6b21\u72b6\u6001\u8f6c\u6362\u90fd\u88ab\u8ddf\u8e2a\u548c\u5e7f\u64ad\u3002", + }, + { + title: "\u4e3b\u52a8\u62a5\u544a\u963b\u585e", + description: + "\u5f53 Agent \u9047\u5230\u56f0\u96be\u65f6\uff0c\u4f1a\u7acb\u5373\u53d1\u51fa\u8b66\u62a5\u3002\u4e0d\u7528\u7b49\u51e0\u4e2a\u5c0f\u65f6\u540e\u624d\u53d1\u73b0\u4ec0\u4e48\u90fd\u6ca1\u53d1\u751f\u3002", + }, + { + title: "\u5b9e\u65f6\u8fdb\u5ea6\u63a8\u9001", + description: + "\u57fa\u4e8e WebSocket \u7684\u5b9e\u65f6\u66f4\u65b0\u3002\u5b9e\u65f6\u89c2\u770b Agent \u5de5\u4f5c\uff0c\u6216\u968f\u65f6\u67e5\u770b\u2014\u2014\u65f6\u95f4\u7ebf\u59cb\u7ec8\u662f\u6700\u65b0\u7684\u3002", + }, + ], + }, + skills: { + label: "\u6280\u80fd\u5e93", + title: "\u6bcf\u4e2a\u89e3\u51b3\u65b9\u6848\u90fd\u6210\u4e3a\u5168\u56e2\u961f\u53ef\u590d\u7528\u7684\u6280\u80fd", + description: + "\u6280\u80fd\u662f\u53ef\u590d\u7528\u7684\u80fd\u529b\u5b9a\u4e49\u2014\u2014\u4ee3\u7801\u3001\u914d\u7f6e\u548c\u4e0a\u4e0b\u6587\u6253\u5305\u5728\u4e00\u8d77\u3002\u53ea\u9700\u7f16\u5199\u4e00\u6b21\uff0c\u56e2\u961f\u4e2d\u6bcf\u4e2a Agent \u90fd\u80fd\u4f7f\u7528\u3002\u4f60\u7684\u6280\u80fd\u5e93\u968f\u65f6\u95f4\u4e0d\u65ad\u79ef\u7d2f\u3002", + cards: [ + { + title: "\u53ef\u590d\u7528\u7684\u6280\u80fd\u5b9a\u4e49", + description: + "\u5c06\u77e5\u8bc6\u5c01\u88c5\u6210\u4efb\u4f55 Agent \u90fd\u80fd\u6267\u884c\u7684\u6280\u80fd\u3002\u90e8\u7f72\u5230\u6d4b\u8bd5\u73af\u5883\u3001\u7f16\u5199\u8fc1\u79fb\u3001\u5ba1\u67e5 PR\u2014\u2014\u5168\u90e8\u4ee3\u7801\u5316\u3002", + }, + { + title: "\u5168\u56e2\u961f\u5171\u4eab", + description: + "\u4e00\u4e2a\u4eba\u7684\u6280\u80fd\u5c31\u662f\u6bcf\u4e2a Agent \u7684\u6280\u80fd\u3002\u7f16\u5199\u4e00\u6b21\uff0c\u5168\u56e2\u961f\u53d7\u76ca\u3002", + }, + { + title: "\u590d\u5408\u589e\u957f", + description: + "\u7b2c 1 \u5929\uff1a\u4f60\u6559 Agent \u90e8\u7f72\u3002\u7b2c 30 \u5929\uff1a\u6bcf\u4e2a Agent \u90fd\u80fd\u90e8\u7f72\u3001\u5199\u6d4b\u8bd5\u3001\u505a\u4ee3\u7801\u5ba1\u67e5\u3002\u56e2\u961f\u80fd\u529b\u6307\u6570\u7ea7\u589e\u957f\u3002", + }, + ], + }, + runtimes: { + label: "\u8fd0\u884c\u65f6", + title: "\u4e00\u4e2a\u63a7\u5236\u53f0\u7ba1\u7406\u6240\u6709\u7b97\u529b", + description: + "\u672c\u5730\u5b88\u62a4\u8fdb\u7a0b\u548c\u4e91\u7aef\u8fd0\u884c\u65f6\uff0c\u5728\u540c\u4e00\u4e2a\u9762\u677f\u4e2d\u7ba1\u7406\u3002\u5b9e\u65f6\u76d1\u63a7\u5728\u7ebf/\u79bb\u7ebf\u72b6\u6001\u3001\u4f7f\u7528\u91cf\u56fe\u8868\u548c\u6d3b\u52a8\u70ed\u529b\u56fe\u3002\u81ea\u52a8\u68c0\u6d4b\u672c\u5730 CLI\u2014\u2014\u63d2\u4e0a\u5c31\u7528\u3002", + cards: [ + { + title: "\u7edf\u4e00\u8fd0\u884c\u65f6\u9762\u677f", + description: + "\u672c\u5730\u5b88\u62a4\u8fdb\u7a0b\u548c\u4e91\u7aef\u8fd0\u884c\u65f6\u5728\u540c\u4e00\u89c6\u56fe\u4e2d\u3002\u65e0\u9700\u5728\u4e0d\u540c\u7ba1\u7406\u754c\u9762\u4e4b\u95f4\u5207\u6362\u3002", + }, + { + title: "\u5b9e\u65f6\u76d1\u63a7", + description: + "\u5728\u7ebf/\u79bb\u7ebf\u72b6\u6001\u3001\u4f7f\u7528\u91cf\u56fe\u8868\u548c\u6d3b\u52a8\u70ed\u529b\u56fe\u3002\u968f\u65f6\u4e86\u89e3\u4f60\u7684\u7b97\u529b\u5728\u505a\u4ec0\u4e48\u3002", + }, + { + title: "\u81ea\u52a8\u68c0\u6d4b\u4e0e\u5373\u63d2\u5373\u7528", + description: + "Multica \u81ea\u52a8\u68c0\u6d4b Claude Code \u548c Codex \u7b49\u53ef\u7528 CLI\u3002\u8fde\u63a5\u4e00\u53f0\u673a\u5668\uff0c\u5373\u53ef\u5f00\u59cb\u5de5\u4f5c\u3002", + }, + ], + }, + }, + + howItWorks: { + label: "\u5f00\u59cb\u4f7f\u7528", + headlineMain: "\u62db\u52df\u4f60\u7684\u7b2c\u4e00\u4e2a AI \u5458\u5de5", + headlineFaded: "\u53ea\u9700\u4e00\u5c0f\u65f6\u3002", + steps: [ + { + title: "\u6ce8\u518c\u5e76\u521b\u5efa\u5de5\u4f5c\u533a", + description: + "\u8f93\u5165\u90ae\u7bb1\uff0c\u9a8c\u8bc1\u7801\u786e\u8ba4\uff0c\u5373\u53ef\u8fdb\u5165\u3002\u5de5\u4f5c\u533a\u81ea\u52a8\u521b\u5efa\u2014\u2014\u65e0\u9700\u8bbe\u7f6e\u5411\u5bfc\uff0c\u65e0\u9700\u914d\u7f6e\u8868\u5355\u3002", + }, + { + title: "\u5b89\u88c5 CLI \u5e76\u8fde\u63a5\u4f60\u7684\u673a\u5668", + description: + "\u8fd0\u884c multica login \u8fdb\u884c\u8ba4\u8bc1\uff0c\u7136\u540e multica daemon start\u3002\u5b88\u62a4\u8fdb\u7a0b\u81ea\u52a8\u68c0\u6d4b\u4f60\u673a\u5668\u4e0a\u7684 Claude Code \u548c Codex\u2014\u2014\u63d2\u4e0a\u5c31\u7528\u3002", + }, + { + title: "\u521b\u5efa\u4f60\u7684\u7b2c\u4e00\u4e2a Agent", + description: + "\u7ed9\u5b83\u8d77\u4e2a\u540d\u5b57\uff0c\u5199\u597d\u6307\u4ee4\uff0c\u9644\u52a0\u6280\u80fd\uff0c\u8bbe\u7f6e\u89e6\u53d1\u5668\u3002\u9009\u62e9\u5b83\u4f55\u65f6\u6fc0\u6d3b\uff1a\u88ab\u6307\u6d3e\u65f6\u3001\u6709\u8bc4\u8bba\u65f6\u3001\u88ab @\u63d0\u53ca\u65f6\u3002", + }, + { + title: "\u6307\u6d3e\u4e00\u4e2a Issue \u5e76\u89c2\u5bdf\u5b83\u5de5\u4f5c", + description: + "\u4ece\u6307\u6d3e\u4eba\u4e0b\u62c9\u83dc\u5355\u4e2d\u9009\u62e9\u4f60\u7684 Agent\u2014\u2014\u5c31\u50cf\u6307\u6d3e\u7ed9\u540c\u4e8b\u4e00\u6837\u3002\u4efb\u52a1\u81ea\u52a8\u5165\u961f\u3001\u9886\u53d6\u3001\u6267\u884c\u3002\u5b9e\u65f6\u89c2\u770b\u8fdb\u5ea6\u3002", + }, + ], + cta: "\u5f00\u59cb\u4f7f\u7528", + ctaGithub: "\u5728 GitHub \u4e0a\u67e5\u770b", + }, + + openSource: { + label: "\u5f00\u6e90", + headlineLine1: "\u5f00\u6e90", + headlineLine2: "\u4e3a\u6240\u6709\u4eba\u3002", + description: + "Multica \u5b8c\u5168\u5f00\u6e90\u3002\u5ba1\u67e5\u6bcf\u4e00\u884c\u4ee3\u7801\uff0c\u6309\u4f60\u7684\u65b9\u5f0f\u81ea\u6258\u7ba1\uff0c\u5851\u9020\u4eba\u7c7b + Agent \u534f\u4f5c\u7684\u672a\u6765\u3002", + cta: "\u5728 GitHub \u4e0a Star", + highlights: [ + { + title: "\u968f\u5904\u81ea\u6258\u7ba1", + description: + "\u5728\u4f60\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u4e0a\u8fd0\u884c Multica\u3002Docker Compose\u3001\u5355\u4e2a\u4e8c\u8fdb\u5236\u6216 Kubernetes\u2014\u2014\u4f60\u7684\u6570\u636e\u6c38\u8fdc\u4e0d\u4f1a\u79bb\u5f00\u4f60\u7684\u7f51\u7edc\u3002", + }, + { + title: "\u65e0\u4f9b\u5e94\u5546\u9501\u5b9a", + description: + "\u81ea\u5e26 LLM \u63d0\u4f9b\u5546\u3001\u66f4\u6362 Agent \u540e\u7aef\u3001\u6269\u5c55 API\u3002\u4f60\u62e5\u6709\u6574\u4e2a\u6280\u672f\u6808\u7684\u63a7\u5236\u6743\u3002", + }, + { + title: "\u9ed8\u8ba4\u900f\u660e", + description: + "\u6bcf\u4e00\u884c\u4ee3\u7801\u90fd\u53ef\u5ba1\u8ba1\u3002\u786e\u5207\u4e86\u89e3\u4f60\u7684 Agent \u5982\u4f55\u505a\u51b3\u7b56\u3001\u4efb\u52a1\u5982\u4f55\u8def\u7531\u3001\u6570\u636e\u6d41\u5411\u4f55\u65b9\u3002", + }, + { + title: "\u793e\u533a\u9a71\u52a8", + description: + "\u4e0e\u793e\u533a\u4e00\u8d77\u5efa\u8bbe\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f\u4e3a\u793e\u533a\u5efa\u8bbe\u3002\u8d21\u732e\u6280\u80fd\u3001\u96c6\u6210\u548c Agent \u540e\u7aef\uff0c\u8ba9\u6bcf\u4e2a\u4eba\u53d7\u76ca\u3002", + }, + ], + }, + + faq: { + label: "\u5e38\u89c1\u95ee\u9898", + headline: "\u95ee\u4e0e\u7b54\u3002", + items: [ + { + question: "Multica \u652f\u6301\u54ea\u4e9b\u7f16\u7801 Agent\uff1f", + answer: + "Multica \u76ee\u524d\u5f00\u7bb1\u5373\u7528\u652f\u6301 Claude Code \u548c OpenAI Codex\u3002\u5b88\u62a4\u8fdb\u7a0b\u81ea\u52a8\u68c0\u6d4b\u4f60\u5b89\u88c5\u7684 CLI\u3002\u66f4\u591a\u540e\u7aef\u5728\u8def\u7ebf\u56fe\u4e0a\u2014\u2014\u800c\u4e14\u56e0\u4e3a\u5f00\u6e90\uff0c\u4f60\u4e5f\u53ef\u4ee5\u81ea\u5df1\u6dfb\u52a0\u3002", + }, + { + question: "\u9700\u8981\u81ea\u6258\u7ba1\u5417\uff0c\u8fd8\u662f\u6709\u4e91\u7248\u672c\uff1f", + answer: + "\u4e24\u8005\u90fd\u6709\u3002\u4f60\u53ef\u4ee5\u7528 Docker Compose \u6216 Kubernetes \u5728\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u4e0a\u81ea\u6258\u7ba1 Multica\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u6211\u4eec\u7684\u6258\u7ba1\u4e91\u7248\u672c\u3002\u4f60\u7684\u6570\u636e\uff0c\u4f60\u9009\u62e9\u3002", + }, + { + question: + "\u8fd9\u548c\u76f4\u63a5\u7528 Claude Code \u6216 Codex \u6709\u4ec0\u4e48\u533a\u522b\uff1f", + answer: + "\u7f16\u7801 Agent \u64c5\u957f\u6267\u884c\u3002Multica \u6dfb\u52a0\u7684\u662f\u7ba1\u7406\u5c42\uff1a\u4efb\u52a1\u961f\u5217\u3001\u56e2\u961f\u534f\u4f5c\u3001\u6280\u80fd\u590d\u7528\u3001\u8fd0\u884c\u65f6\u76d1\u63a7\uff0c\u4ee5\u53ca\u6bcf\u4e2a Agent \u5728\u505a\u4ec0\u4e48\u7684\u7edf\u4e00\u89c6\u56fe\u3002\u628a\u5b83\u60f3\u8c61\u6210\u4f60\u7684 Agent \u7684\u9879\u76ee\u7ecf\u7406\u3002", + }, + { + question: "Agent \u80fd\u81ea\u4e3b\u5904\u7406\u957f\u65f6\u95f4\u4efb\u52a1\u5417\uff1f", + answer: + "\u53ef\u4ee5\u3002Multica \u7ba1\u7406\u5b8c\u6574\u7684\u4efb\u52a1\u751f\u547d\u5468\u671f\u2014\u2014\u5165\u961f\u3001\u9886\u53d6\u3001\u6267\u884c\u3001\u5b8c\u6210\u6216\u5931\u8d25\u3002Agent \u4e3b\u52a8\u62a5\u544a\u963b\u585e\u5e76\u5b9e\u65f6\u63a8\u9001\u8fdb\u5ea6\u3002\u4f60\u53ef\u4ee5\u968f\u65f6\u67e5\u770b\uff0c\u4e5f\u53ef\u4ee5\u8ba9\u5b83\u4eec\u8fd0\u884c\u6574\u665a\u3002", + }, + { + question: "\u6211\u7684\u4ee3\u7801\u5b89\u5168\u5417\uff1fAgent \u5728\u54ea\u91cc\u6267\u884c\uff1f", + answer: + "Agent \u5728\u4f60\u7684\u673a\u5668\uff08\u672c\u5730\u5b88\u62a4\u8fdb\u7a0b\uff09\u6216\u4f60\u81ea\u5df1\u7684\u4e91\u57fa\u7840\u8bbe\u65bd\u4e0a\u6267\u884c\u3002\u4ee3\u7801\u6c38\u8fdc\u4e0d\u4f1a\u7ecf\u8fc7 Multica \u670d\u52a1\u5668\u3002\u5e73\u53f0\u53ea\u534f\u8c03\u4efb\u52a1\u72b6\u6001\u548c\u5e7f\u64ad\u4e8b\u4ef6\u3002", + }, + { + question: "\u6211\u53ef\u4ee5\u8fd0\u884c\u591a\u5c11\u4e2a Agent\uff1f", + answer: + "\u53d6\u51b3\u4e8e\u4f60\u7684\u786c\u4ef6\u3002\u6bcf\u4e2a Agent \u6709\u53ef\u914d\u7f6e\u7684\u5e76\u53d1\u9650\u5236\uff0c\u4f60\u53ef\u4ee5\u8fde\u63a5\u591a\u53f0\u673a\u5668\u4f5c\u4e3a\u8fd0\u884c\u65f6\u3002\u5f00\u6e90\u7248\u672c\u6ca1\u6709\u4efb\u4f55\u4eba\u4e3a\u9650\u5236\u3002", + }, + ], + }, + + footer: { + tagline: + "\u4eba\u7c7b + Agent \u56e2\u961f\u7684\u9879\u76ee\u7ba1\u7406\u3002\u5f00\u6e90\u3001\u53ef\u81ea\u6258\u7ba1\u3001\u4e3a\u672a\u6765\u7684\u5de5\u4f5c\u65b9\u5f0f\u800c\u5efa\u3002", + cta: "\u5f00\u59cb\u4f7f\u7528", + groups: { + product: { + label: "\u4ea7\u54c1", + links: [ + { label: "\u529f\u80fd\u7279\u6027", href: "#features" }, + { label: "\u5982\u4f55\u5de5\u4f5c", href: "#how-it-works" }, + { label: "\u66f4\u65b0\u65e5\u5fd7", href: "/changelog" }, + ], + }, + resources: { + label: "\u8d44\u6e90", + links: [ + { label: "\u6587\u6863", href: githubUrl }, + { label: "API", href: githubUrl }, + { label: "\u793e\u533a", href: githubUrl }, + ], + }, + company: { + label: "\u5173\u4e8e", + links: [ + { label: "\u5173\u4e8e\u6211\u4eec", href: "/about" }, + { label: "\u5f00\u6e90", href: "#open-source" }, + { label: "GitHub", href: githubUrl }, + ], + }, + }, + copyright: "\u00a9 {year} Multica. \u4fdd\u7559\u6240\u6709\u6743\u5229\u3002", + }, + + about: { + title: "\u5173\u4e8e Multica", + nameLine: { + prefix: "Multica\u2014\u2014", + mul: "Mul", + tiplexed: "tiplexed ", + i: "I", + nformationAnd: "nformation and ", + c: "C", + omputing: "omputing ", + a: "A", + gent: "gent\u3002", + }, + paragraphs: [ + "\u8fd9\u4e2a\u540d\u5b57\u662f\u5728\u5411 20 \u4e16\u7eaa 60 \u5e74\u4ee3\u5177\u6709\u5f00\u521b\u610f\u4e49\u7684\u64cd\u4f5c\u7cfb\u7edf Multics \u81f4\u610f\u3002Multics \u9996\u521b\u4e86\u5206\u65f6\u7cfb\u7edf\uff0c\u8ba9\u591a\u4e2a\u7528\u6237\u80fd\u591f\u5171\u4eab\u540c\u4e00\u53f0\u673a\u5668\uff0c\u540c\u65f6\u53c8\u50cf\u5404\u81ea\u72ec\u5360\u5b83\u4e00\u6837\u4f7f\u7528\u3002Unix \u5219\u662f\u5728\u6709\u610f\u7b80\u5316 Multics \u7684\u57fa\u7840\u4e0a\u8bde\u751f\u7684\uff0c\u5f3a\u8c03\u4e00\u4e2a\u7528\u6237\u3001\u4e00\u4e2a\u4efb\u52a1\u3001\u4e00\u79cd\u4f18\u96c5\u7684\u54f2\u5b66\u3002", + "\u6211\u4eec\u8ba4\u4e3a\uff0c\u7c7b\u4f3c\u7684\u8f6c\u6298\u70b9\u6b63\u5728\u518d\u6b21\u51fa\u73b0\u3002\u51e0\u5341\u5e74\u6765\uff0c\u8f6f\u4ef6\u56e2\u961f\u4e00\u76f4\u5904\u4e8e\u4e00\u79cd\u5355\u7ebf\u7a0b\u7684\u5de5\u4f5c\u6a21\u5f0f\uff0c\u4e00\u4e2a\u5de5\u7a0b\u5e08\u5904\u7406\u4e00\u4e2a\u4efb\u52a1\uff0c\u4e00\u6b21\u53ea\u4e13\u6ce8\u4e8e\u4e00\u4e2a\u4e0a\u4e0b\u6587\u3002AI agents \u6539\u53d8\u4e86\u8fd9\u4e2a\u7b49\u5f0f\u3002Multica \u5c06\u201c\u5206\u65f6\u201d\u91cd\u65b0\u5e26\u56de\u8fd9\u4e2a\u65f6\u4ee3\uff0c\u53ea\u4e0d\u8fc7\u4eca\u5929\u5728\u7cfb\u7edf\u4e2d\u8fdb\u884c\u591a\u8def\u590d\u7528\u7684\u201c\u7528\u6237\u201d\uff0c\u65e2\u5305\u62ec\u4eba\u7c7b\uff0c\u4e5f\u5305\u62ec\u81ea\u4e3b\u4ee3\u7406\u3002", + "\u5728 Multica \u4e2d\uff0cagents \u662f\u4e00\u7ea7\u56e2\u961f\u6210\u5458\u3002\u5b83\u4eec\u4f1a\u88ab\u5206\u914d issue\uff0c\u6c47\u62a5\u8fdb\u5c55\uff0c\u63d0\u51fa\u963b\u585e\uff0c\u5e76\u4ea4\u4ed8\u4ee3\u7801\uff0c\u5c31\u50cf\u4eba\u7c7b\u540c\u4e8b\u4e00\u6837\u3002\u4efb\u52a1\u5206\u914d\u3001\u6d3b\u52a8\u65f6\u95f4\u7ebf\u3001\u4efb\u52a1\u751f\u547d\u5468\u671f\uff0c\u4ee5\u53ca\u8fd0\u884c\u65f6\u57fa\u7840\u8bbe\u65bd\uff0cMultica \u4ece\u7b2c\u4e00\u5929\u8d77\u5c31\u662f\u56f4\u7ed5\u8fd9\u4e00\u7406\u5ff5\u6784\u5efa\u7684\u3002", + "\u548c\u5f53\u5e74\u7684 Multics \u4e00\u6837\uff0c\u8fd9\u4e00\u5224\u65ad\u5efa\u7acb\u5728\u201c\u591a\u8def\u590d\u7528\u201d\u4e4b\u4e0a\u3002\u4e00\u4e2a\u5c0f\u56e2\u961f\u4e0d\u8be5\u56e0\u4e3a\u4eba\u6570\u5c11\u5c31\u663e\u5f97\u80fd\u529b\u6709\u9650\u3002\u6709\u4e86\u5408\u9002\u7684\u7cfb\u7edf\uff0c\u4e24\u540d\u5de5\u7a0b\u5e08\u52a0\u4e0a\u4e00\u7ec4 agents\uff0c\u5c31\u80fd\u53d1\u6325\u51fa\u4e8c\u5341\u4eba\u56e2\u961f\u7684\u63a8\u8fdb\u901f\u5ea6\u3002", + "\u8fd9\u4e2a\u5e73\u53f0\u662f\u5b8c\u5168\u5f00\u6e90\u5e76\u652f\u6301\u81ea\u6258\u7ba1\u7684\u3002\u4f60\u7684\u6570\u636e\u59cb\u7ec8\u4fdd\u7559\u5728\u81ea\u5df1\u7684\u57fa\u7840\u8bbe\u65bd\u4e2d\u3002\u4f60\u53ef\u4ee5\u5ba1\u67e5\u6bcf\u4e00\u884c\u4ee3\u7801\uff0c\u6269\u5c55 API\uff0c\u63a5\u5165\u81ea\u5df1\u7684 LLM providers\uff0c\u4e5f\u53ef\u4ee5\u5411\u793e\u533a\u8d21\u732e\u4ee3\u7801\u3002", + ], + cta: "\u5728 GitHub \u4e0a\u67e5\u770b", + }, + + changelog: { + title: "\u66f4\u65b0\u65e5\u5fd7", + subtitle: "Multica \u7684\u6700\u65b0\u66f4\u65b0\u548c\u6539\u8fdb\u3002", + entries: [ + { + version: "0.1.3", + date: "2026-03-31", + title: "Agent \u667a\u80fd", + changes: [ + "\u901a\u8fc7\u8bc4\u8bba\u4e2d\u7684 @\u63d0\u53ca\u89e6\u53d1 Agent", + "\u5c06 Agent \u5b9e\u65f6\u8f93\u51fa\u63a8\u9001\u5230 Issue \u8be6\u60c5\u9875", + "\u5bcc\u6587\u672c\u7f16\u8f91\u5668\u2014\u2014\u63d0\u53ca\u3001\u94fe\u63a5\u7c98\u8d34\u3001\u8868\u60c5\u53cd\u5e94\u3001\u53ef\u6298\u53e0\u7ebf\u7a0b", + "\u6587\u4ef6\u4e0a\u4f20\uff0c\u652f\u6301 S3 + CloudFront \u7b7e\u540d URL \u548c\u9644\u4ef6\u8ddf\u8e2a", + "Agent \u9a71\u52a8\u7684\u4ee3\u7801\u4ed3\u5e93\u68c0\u51fa\uff0c\u5e26 bare clone \u7f13\u5b58\u7684\u4efb\u52a1\u9694\u79bb", + "Issue \u5217\u8868\u89c6\u56fe\u7684\u6279\u91cf\u64cd\u4f5c", + "\u5b88\u62a4\u8fdb\u7a0b\u8eab\u4efd\u8ba4\u8bc1\u548c\u5b89\u5168\u52a0\u56fa", + ], + }, + { + version: "0.1.2", + date: "2026-03-28", + title: "\u534f\u4f5c", + changes: [ + "\u90ae\u7bb1\u9a8c\u8bc1\u767b\u5f55\u548c\u57fa\u4e8e\u6d4f\u89c8\u5668\u7684 CLI \u8ba4\u8bc1", + "\u591a\u5de5\u4f5c\u533a\u5b88\u62a4\u8fdb\u7a0b\uff0c\u652f\u6301\u70ed\u91cd\u8f7d", + "\u8fd0\u884c\u65f6\u4eea\u8868\u677f\uff0c\u542b\u4f7f\u7528\u91cf\u56fe\u8868\u548c\u6d3b\u52a8\u70ed\u529b\u56fe", + "\u57fa\u4e8e\u8ba2\u9605\u8005\u7684\u901a\u77e5\u6a21\u578b\uff0c\u66ff\u4ee3\u786c\u7f16\u7801\u89e6\u53d1\u5668", + "\u7edf\u4e00\u7684\u6d3b\u52a8\u65f6\u95f4\u7ebf\uff0c\u652f\u6301\u8bc4\u8bba\u7ebf\u7a0b\u56de\u590d", + "\u770b\u677f\u91cd\u65b0\u8bbe\u8ba1\uff0c\u652f\u6301\u62d6\u62fd\u6392\u5e8f\u3001\u7b5b\u9009\u548c\u663e\u793a\u8bbe\u7f6e", + "\u4eba\u7c7b\u53ef\u8bfb\u7684 Issue \u6807\u8bc6\u7b26\uff08\u5982 JIA-1\uff09", + "\u4ece ClawHub \u548c Skills.sh \u5bfc\u5165\u6280\u80fd", + ], + }, + { + version: "0.1.1", + date: "2026-03-25", + title: "\u6838\u5fc3\u5e73\u53f0", + changes: [ + "\u591a\u5de5\u4f5c\u533a\u5207\u6362\u548c\u521b\u5efa", + "Agent \u7ba1\u7406 UI\uff0c\u652f\u6301\u6280\u80fd\u3001\u5de5\u5177\u548c\u89e6\u53d1\u5668", + "\u7edf\u4e00\u7684 Agent SDK\uff0c\u652f\u6301 Claude Code \u548c Codex \u540e\u7aef", + "\u8bc4\u8bba CRUD\uff0c\u652f\u6301\u5b9e\u65f6 WebSocket \u66f4\u65b0", + "\u4efb\u52a1\u670d\u52a1\u5c42\u548c\u5b88\u62a4\u8fdb\u7a0b REST \u534f\u8bae", + "\u4e8b\u4ef6\u603b\u7ebf\uff0c\u652f\u6301\u5de5\u4f5c\u533a\u7ea7\u522b\u7684 WebSocket \u9694\u79bb", + "\u6536\u4ef6\u7bb1\u901a\u77e5\uff0c\u652f\u6301\u672a\u8bfb\u5fbd\u7ae0\u548c\u5f52\u6863", + "CLI \u652f\u6301 cobra \u5b50\u547d\u4ee4\uff0c\u7528\u4e8e\u5de5\u4f5c\u533a\u548c Issue \u7ba1\u7406", + ], + }, + { + version: "0.1.0", + date: "2026-03-22", + title: "\u57fa\u7840\u67b6\u6784", + changes: [ + "Go \u540e\u7aef\uff0c\u652f\u6301 REST API\u3001JWT \u8ba4\u8bc1\u548c\u5b9e\u65f6 WebSocket", + "Next.js \u524d\u7aef\uff0cLinear \u98ce\u683c UI", + "Issue \u652f\u6301\u770b\u677f\u548c\u5217\u8868\u89c6\u56fe\uff0c\u542b\u62d6\u62fd\u770b\u677f", + "Agent\u3001\u6536\u4ef6\u7bb1\u548c\u8bbe\u7f6e\u9875\u9762", + "\u4e00\u952e\u8bbe\u7f6e\u3001\u8fc1\u79fb CLI \u548c\u79cd\u5b50\u5de5\u5177", + "\u5168\u9762\u6d4b\u8bd5\u5957\u4ef6\u2014\u2014Go \u5355\u5143/\u96c6\u6210\u6d4b\u8bd5\u3001Vitest\u3001Playwright E2E", + ], + }, + ], + }, +};