docs: show ReMe ecosystem on homepage (#568)
Some checks failed
CI / Python quality / GitHub Actions (push) Waiting to run
CI / Python quality / Pre-commit (push) Waiting to run
CI / Python tests / Unit Tests - py3.11 (push) Waiting to run
CI / Python tests / Unit Tests - py3.12 (push) Waiting to run
CI / Python tests / Unit Tests - py3.13 (push) Waiting to run
CI / Python tests / Unit Tests - py3.14 (push) Waiting to run
CI / Windows / CLI smoke - py3.11 (push) Waiting to run
Security / CodeQL / Analyze javascript-typescript (push) Waiting to run
Security / CodeQL / Analyze python (push) Waiting to run
Deploy / Documentation / Build documentation (push) Has been cancelled
Deploy / Documentation / deploy (push) Has been cancelled

* docs: show ReMe ecosystem on homepage

* fix(docs): prevent hero title from overlapping ecosystem column

At 1366x768 the English headline used white-space: pre inside a
left column squeezed to ~538px by the 650px right column, so it
overflowed onto the ecosystem map (review comment on #568).

- use white-space: pre-wrap so the headline wraps within its column
- stack the hero to a single column below 1680px (benchmark/traffic
  sections keep their original 1320px breakpoint)
- pin the ecosystem column to 650px and cap the headline at 76px so
  the two-line headline fits beside it at 1681px and wider

Co-Authored-By: Claude Code <noreply@anthropic.com>

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
This commit is contained in:
jinliyl 2026-09-24 11:58:05 +08:00 • committed by GitHub
parent c9a9728164
commit 8b5456641f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 236 additions and 55 deletions

View file

@ -18,13 +18,30 @@ const translations = {
learnMore: "了解 ReMe",
stars: "GitHub Stars",
forks: "Forks",
mapLabel: "SHARED MEMORY WORKSPACE",
mapTitle: "一层记忆,连接所有 Agent",
mapLabel: "OPEN ECOSYSTEM",
mapTitle: "ReMe 与开源生态",
capabilityTitle: "核心能力",
capabilities: [
{ icon: "▱", title: "文件即记忆", detail: "用户拥有的文件是持久事实源", href: "/zh/memory_as_file", tone: "mint" },
{ icon: "✦", title: "自动记忆", detail: "从 daily 到长期 digest 持续演化", href: "/zh/auto_memory", tone: "cyan" },
{ icon: "⌕", title: "检索与图谱", detail: "关键词、向量与 wikilink 联合召回", href: "/zh/memory_search", tone: "blue" },
{ icon: "⌁", title: "Agent 集成", detail: "通过 CLI、HTTP、MCP 与宿主适配器接入", href: "/zh/integrations", tone: "amber" },
{ mark: "▣", title: "文件即记忆", href: "/zh/memory_as_file", tone: "mint" },
{ mark: "✦", title: "自动记忆", href: "/zh/auto_memory", tone: "cyan" },
{ mark: "⌕", title: "混合检索", href: "/zh/memory_search", tone: "blue" },
{ mark: "⌁", title: "图谱关联", href: "/zh/auto_link", tone: "amber" },
],
agentTitle: "ReMe 接入 Agent",
agentGuide: "接入指南",
backendTitle: "检索引擎接入 ReMe",
backendGuide: "配置指南",
backendNote: "可选向量索引",
integrations: [
{ logo: "/ecosystem/qwenpaw.png", title: "QwenPaw", href: "https://github.com/agentscope-ai/QwenPaw", tone: "blue" },
{ logo: "/ecosystem/deepseek-harness.svg", title: "DeepSeek Harness", href: "https://github.com/deepseek-ai/deepseek-harness", tone: "mint" },
{ logo: "/ecosystem/openclaw.svg", title: "OpenClaw", href: "https://github.com/openclaw/openclaw", tone: "cyan" },
{ logo: "/ecosystem/claude-code.png", title: "Claude Code", href: "https://github.com/anthropics/claude-code", tone: "violet" },
{ logo: "/ecosystem/hermes.svg", title: "Hermes Agent", href: "https://github.com/NousResearch/hermes-agent", tone: "amber" },
],
backends: [
{ logo: "/ecosystem/zvec.ico", title: "Zvec", href: "https://github.com/alibaba/zvec", tone: "mint" },
{ logo: "/ecosystem/faiss.png", title: "FAISS", href: "https://github.com/facebookresearch/faiss", tone: "blue" },
],
benchmarkLabel: "02 / BENCHMARKS",
benchmarkTitle: "用真实评测,\n验证长期记忆",
@ -61,13 +78,30 @@ const translations = {
learnMore: "Meet ReMe",
stars: "GitHub Stars",
forks: "Forks",
mapLabel: "SHARED MEMORY WORKSPACE",
mapTitle: "One memory layer for every agent",
mapLabel: "OPEN ECOSYSTEM",
mapTitle: "ReMe and the open ecosystem",
capabilityTitle: "CORE CAPABILITIES",
capabilities: [
{ icon: "▱", title: "Memory as files", detail: "User-owned files remain the durable source of truth", href: "/en/memory_as_file", tone: "mint" },
{ icon: "✦", title: "Memory workflows", detail: "Evolve daily records into durable, connected digests", href: "/en/auto_memory", tone: "cyan" },
{ icon: "⌕", title: "Search and graph", detail: "Combine keyword, vector, and wikilink retrieval", href: "/en/memory_search", tone: "blue" },
{ icon: "⌁", title: "Agent integrations", detail: "Connect through CLI, HTTP, MCP, and host adapters", href: "/en/integrations", tone: "amber" },
{ mark: "▣", title: "Memory as files", href: "/en/memory_as_file", tone: "mint" },
{ mark: "✦", title: "Auto memory", href: "/en/auto_memory", tone: "cyan" },
{ mark: "⌕", title: "Hybrid search", href: "/en/memory_search", tone: "blue" },
{ mark: "⌁", title: "Linked graph", href: "/en/auto_link", tone: "amber" },
],
agentTitle: "ReMe for agents",
agentGuide: "Integration guide",
backendTitle: "Retrieval for ReMe",
backendGuide: "Configuration guide",
backendNote: "Optional vector indexes",
integrations: [
{ logo: "/ecosystem/qwenpaw.png", title: "QwenPaw", href: "https://github.com/agentscope-ai/QwenPaw", tone: "blue" },
{ logo: "/ecosystem/deepseek-harness.svg", title: "DeepSeek Harness", href: "https://github.com/deepseek-ai/deepseek-harness", tone: "mint" },
{ logo: "/ecosystem/openclaw.svg", title: "OpenClaw", href: "https://github.com/openclaw/openclaw", tone: "cyan" },
{ logo: "/ecosystem/claude-code.png", title: "Claude Code", href: "https://github.com/anthropics/claude-code", tone: "violet" },
{ logo: "/ecosystem/hermes.svg", title: "Hermes Agent", href: "https://github.com/NousResearch/hermes-agent", tone: "amber" },
],
backends: [
{ logo: "/ecosystem/zvec.ico", title: "Zvec", href: "https://github.com/alibaba/zvec", tone: "mint" },
{ logo: "/ecosystem/faiss.png", title: "FAISS", href: "https://github.com/facebookresearch/faiss", tone: "blue" },
],
benchmarkLabel: "02 / BENCHMARKS",
benchmarkTitle: "Memory that holds up\nunder pressure",
@ -120,7 +154,6 @@ onMounted(async () => {
if (forks.status === "fulfilled" && forks.value) stats.forks = forks.value;
});
</script>
<template>
<div class="reme-home" :class="{ 'is-zh': lang === 'zh' }">
<section class="home-stage">
@ -146,30 +179,64 @@ onMounted(async () => {
</div>
</div>
<div class="capability-map">
<div class="ecosystem-map">
<div class="map-heading">
<div>
<span>{{ text.mapLabel }}</span>
<strong>{{ text.mapTitle }}</strong>
</div>
<img :src="localLink('/reme-icon.svg')" alt="" aria-hidden="true" />
</div>
<div class="map-grid">
<a
v-for="(capability, index) in text.capabilities"
:key="capability.title"
class="capability-card"
:class="capability.tone"
:href="localLink(capability.href)"
>
<span class="capability-index">0{{ index + 1 }}</span>
<span class="capability-icon" aria-hidden="true">{{ capability.icon }}</span>
<div class="capability-copy">
<strong>{{ capability.title }}</strong>
<small>{{ capability.detail }}</small>
<div class="ecosystem-network">
<div class="network-brands">
<div class="network-group-label">
<strong>{{ text.agentTitle }}</strong>
<a :href="localLink(`/${lang}/integrations`)">{{ text.agentGuide }} ↗</a>
</div>
<span class="card-arrow">↗</span>
</a>
<div class="brand-viewport">
<div class="brand-reel">
<a
v-for="integration in text.integrations"
:key="integration.title"
class="brand-link"
:class="integration.tone"
:href="integration.href"
target="_blank"
rel="noopener noreferrer"
:aria-label="`${integration.title} GitHub`"
>
<span class="brand-mark" aria-hidden="true"><img :src="localLink(integration.logo)" alt="" /></span>
<strong>{{ integration.title }}</strong>
</a>
<div v-for="integration in text.integrations" :key="`${integration.title}-clone`" class="brand-link reel-clone" :class="integration.tone" aria-hidden="true">
<span class="brand-mark"><img :src="localLink(integration.logo)" alt="" /></span>
<strong>{{ integration.title }}</strong>
</div>
</div>
</div>
<div class="network-group-label backend-label">
<strong>{{ text.backendTitle }}</strong>
<a :href="localLink(`/${lang}/memory_search#${lang === 'zh' ? '向量索引后端' : 'vector-index-backends'}`)">{{ text.backendGuide }} ↗</a>
</div>
<div class="backend-links">
<a v-for="backend in text.backends" :key="backend.title" class="brand-link" :class="backend.tone" :href="backend.href" target="_blank" rel="noopener noreferrer" :aria-label="`${backend.title} GitHub`">
<span class="brand-mark" aria-hidden="true"><img :src="localLink(backend.logo)" alt="" /></span>
<strong>{{ backend.title }}</strong>
</a>
</div>
</div>
<div class="network-center" aria-hidden="true">
<span class="network-ring"></span>
<span class="network-core"><img :src="localLink('/reme-icon.svg')" alt="" /></span>
<strong>ReMe</strong>
</div>
<div class="network-capabilities">
<strong class="capability-label">{{ text.capabilityTitle }}</strong>
<a v-for="capability in text.capabilities" :key="capability.title" class="capability-link" :class="capability.tone" :href="localLink(capability.href)">
<span aria-hidden="true">{{ capability.mark }}</span>
<strong>{{ capability.title }}</strong>
<span aria-hidden="true">↗</span>
</a>
</div>
</div>
</div>
</section>
@ -276,8 +343,8 @@ onMounted(async () => {
.home-stage {
position: relative;
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(460px, 1fr);
gap: clamp(42px, 4.5vw, 78px);
grid-template-columns: minmax(0, 1fr) 650px;
gap: clamp(42px, 4vw, 68px);
align-items: center;
min-height: calc(100vh - 64px);
padding: 72px 0 82px;
@ -293,7 +360,7 @@ onMounted(async () => {
content: "";
}
.eyebrow, .section-label { margin: 0; color: var(--home-accent); font: 750 13px/1.4 var(--vp-font-family-mono); letter-spacing: 0.16em; }
.hero-copy h1 { max-width: 100%; margin: 23px 0 0; color: var(--home-ink); font: 760 clamp(52px, 4.2vw, 78px)/1.04 Georgia, "Times New Roman", serif; white-space: pre; letter-spacing: -0.052em; }
.hero-copy h1 { max-width: 100%; margin: 23px 0 0; color: var(--home-ink); font: 760 clamp(52px, 4.2vw, 76px)/1.04 Georgia, "Times New Roman", serif; white-space: pre-wrap; letter-spacing: -0.052em; }
.is-zh .hero-copy h1 { max-width: 760px; font-size: clamp(52px, 3.6vw, 64px); white-space: pre-line; word-break: keep-all; }
.hero-lead { max-width: 650px; margin: 28px 0 0; color: var(--home-muted); font-size: clamp(17px, 1.3vw, 20px); line-height: 1.75; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
@ -306,22 +373,52 @@ onMounted(async () => {
.fork-icon { transform: rotate(90deg); }
.repo-stats strong { display: block; font: 740 28px/1 var(--vp-font-family-mono); letter-spacing: -0.04em; }
.repo-stats small { display: block; margin-top: 8px; color: var(--home-muted); font-size: 13px; }
.capability-map { position: relative; padding: 21px; border: 1px solid var(--home-line); border-radius: 26px; background: var(--home-glass); box-shadow: 0 30px 70px var(--home-shadow); backdrop-filter: blur(18px); }
.map-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 20px; }
.ecosystem-map { position: relative; min-width: 0; }
.map-heading { margin-bottom: 25px; }
.map-heading > div { display: flex; min-width: 0; flex-direction: column; gap: 8px; }
.map-heading span { color: var(--home-accent); font: 700 10px/1.4 var(--vp-font-family-mono); letter-spacing: 0.12em; }
.map-heading strong { font-size: 18px; line-height: 1.3; white-space: nowrap; }
.map-heading img { width: 42px; height: 42px; flex: none; margin: 0; padding: 6px; border: 1px solid var(--home-line); border-radius: 13px; background: var(--home-tile); box-shadow: 0 8px 18px color-mix(in srgb, var(--home-shadow) 75%, transparent); }
.map-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
.capability-card { position: relative; display: grid; grid-template-columns: 25px 34px minmax(0, 1fr) 16px; gap: 11px; align-items: center; min-height: 96px; padding: 17px 18px; overflow: hidden; border: 1px solid color-mix(in srgb, var(--card-accent) 32%, var(--home-line)); border-radius: 15px; color: var(--home-ink); background: radial-gradient(circle at 92% 8%, color-mix(in srgb, var(--card-accent) 15%, transparent), transparent 42%), var(--home-tile); text-decoration: none; transition: transform 170ms ease, box-shadow 170ms ease; }
.capability-card:hover { transform: translateY(-3px); box-shadow: 0 16px 30px color-mix(in srgb, var(--card-accent) 13%, transparent); }
.ecosystem-network { position: relative; display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(100px, 0.62fr) minmax(0, 1fr); gap: 12px; align-items: center; min-height: 370px; }
.ecosystem-network::before, .ecosystem-network::after { position: absolute; z-index: 0; top: 50%; width: 19%; border-top: 1px dashed color-mix(in srgb, var(--home-accent) 58%, var(--home-line)); content: ""; }
.ecosystem-network::before { left: 30%; }.ecosystem-network::after { right: 27%; }
.network-brands, .network-center, .network-capabilities { position: relative; z-index: 1; min-width: 0; }
.network-group-label { display: flex; align-items: baseline; justify-content: space-between; gap: 5px; margin-bottom: 7px; }
.network-group-label strong, .capability-label { color: var(--home-muted); font: 750 10px/1.3 var(--vp-font-family-mono); letter-spacing: 0.04em; }
.network-group-label a { flex: none; color: var(--home-accent); font-size: 10px; font-weight: 700; text-decoration: none; white-space: nowrap; }
.network-group-label a:hover { text-decoration: underline; }
.brand-viewport { height: 184px; overflow: hidden; mask-image: linear-gradient(transparent, #000 12%, #000 88%, transparent); }
.brand-reel { display: grid; grid-auto-rows: 46px; gap: 6px; animation: brand-scroll 19s linear infinite; }
.brand-viewport:hover .brand-reel { animation-play-state: paused; }
.brand-viewport:focus-within { overflow-y: auto; mask-image: none; }
.brand-viewport:focus-within .brand-reel { animation: none; }
.brand-link { display: flex; min-width: 0; height: 46px; align-items: center; gap: 7px; padding: 5px; border: 1px solid color-mix(in srgb, var(--card-accent) 26%, var(--home-line)); border-radius: 9px; color: var(--home-ink); background: var(--home-tile); text-decoration: none; transition: border-color 160ms ease, transform 160ms ease; }
.brand-link:hover { border-color: var(--card-accent); transform: translateX(2px); }
.brand-mark { display: grid; width: 32px; height: 32px; flex: none; place-items: center; overflow: hidden; border: 1px solid var(--home-line); border-radius: 7px; background: #fff; }
.brand-mark img { width: 27px; height: 27px; margin: 0; object-fit: contain; }
.brand-link strong { min-width: 0; font-size: 13px; line-height: 1.15; overflow-wrap: anywhere; }
.reel-clone { pointer-events: none; }
.backend-label { margin-top: 13px; }
.backend-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
.backend-links .brand-link { height: 42px; gap: 5px; }
.backend-links .brand-mark { width: 28px; height: 28px; }
.backend-links .brand-mark img { width: 23px; height: 23px; }
.network-center { display: flex; min-height: 164px; flex-direction: column; align-items: center; justify-content: center; gap: 16px; }
.network-ring { position: absolute; top: 50%; left: 50%; width: 108px; height: 108px; border: 1px solid color-mix(in srgb, var(--home-accent) 30%, var(--home-line)); border-radius: 50%; transform: translate(-50%, -64%); animation: hub-pulse 3.6s ease-in-out infinite; }
.network-ring::after { position: absolute; inset: 10px; border: 1px solid var(--home-line); border-radius: 50%; content: ""; }
.network-core { z-index: 1; display: grid; width: 64px; height: 64px; place-items: center; border: 1px solid var(--home-line); border-radius: 50%; background: var(--home-surface); box-shadow: 0 10px 28px var(--home-shadow); }
.network-core img { width: 42px; height: 42px; margin: 0; }
.network-center strong { z-index: 1; color: var(--home-accent); font: 750 12px/1 var(--vp-font-family-mono); }
.network-capabilities { display: grid; gap: 8px; }
.capability-label { display: block; margin-bottom: 2px; }
.capability-link { display: flex; min-height: 53px; align-items: center; gap: 7px; padding: 7px; border: 1px solid color-mix(in srgb, var(--card-accent) 30%, var(--home-line)); border-radius: 10px; color: var(--home-ink); background: radial-gradient(circle at 100% 0, color-mix(in srgb, var(--card-accent) 11%, transparent), transparent 70%), var(--home-tile); text-decoration: none; transition: transform 160ms ease, border-color 160ms ease; }
.capability-link:hover { border-color: var(--card-accent); transform: translateX(2px); }
.capability-link span:first-child { display: grid; width: 27px; height: 27px; flex: none; place-items: center; border-radius: 7px; color: var(--card-accent); background: color-mix(in srgb, var(--card-accent) 12%, var(--home-surface)); font-size: 16px; }
.capability-link strong { min-width: 0; font-size: 13px; line-height: 1.2; }
.capability-link span:last-child { margin-left: auto; color: var(--card-accent); font-size: 13px; }
.brand-link:focus-visible, .capability-link:focus-visible, .network-group-label a:focus-visible { outline: 2px solid var(--home-accent); outline-offset: 2px; }
.mint { --card-accent: #059b7f; }.cyan { --card-accent: #169cc4; }.blue { --card-accent: #536bd8; }.amber { --card-accent: #c48324; }.violet { --card-accent: #7654c2; }
.capability-index { color: var(--home-muted); font: 650 10px/1 var(--vp-font-family-mono); letter-spacing: 0.12em; }
.capability-copy { min-width: 0; }
.capability-icon { display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 9px; color: var(--card-accent); background: color-mix(in srgb, var(--card-accent) 13%, var(--home-surface)); font: 600 21px/1 var(--vp-font-family-mono); }
.capability-card strong { display: block; overflow: hidden; font-size: 17px; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
.capability-card small { display: block; overflow: hidden; margin-top: 6px; color: var(--home-muted); font-size: 12px; line-height: 1.45; text-overflow: ellipsis; white-space: nowrap; }
.card-arrow { color: var(--card-accent); font-size: 16px; }
@keyframes brand-scroll { to { transform: translateY(-260px); } }
@keyframes hub-pulse { 50% { transform: translate(-50%, -64%) scale(1.12); opacity: 0.55; } }
.page-panel { position: relative; min-height: calc(100vh - 64px); }
.benchmark-section { display: grid; grid-template-columns: minmax(310px, 0.72fr) minmax(560px, 1.28fr); gap: clamp(54px, 7vw, 110px); align-items: center; padding: 112px 0 120px; color: var(--home-ink); }
.benchmark-section::before { position: absolute; z-index: -1; inset: 0 calc(50% - 50vw); border-top: 1px solid var(--home-line); background: var(--section-tint); content: ""; }
@ -374,12 +471,13 @@ onMounted(async () => {
:global(html.dark .reme-home) { --home-ink: #edf7f3; --home-muted: #a8bbb3; --home-line: #2d4038; --home-accent: #57dfc3; --home-surface: #14201b; --home-surface-soft: #101a16; --home-glass: rgba(17, 28, 23, 0.78); --home-tile: rgba(20, 32, 27, 0.92); --home-primary-bg: #57dfc3; --home-primary-text: #07120e; --home-shadow: rgba(0, 0, 0, 0.3); --section-light: #0d1512; --section-tint: #14201b; color-scheme: dark; }
:global(html.dark .home-stage::before) { background: radial-gradient(ellipse 70% 105% at -8% 18%, rgba(24, 169, 143, 0.13), transparent 72%), radial-gradient(ellipse 68% 105% at 108% 10%, rgba(74, 100, 218, 0.15), transparent 73%), linear-gradient(115deg, #0d1713 0%, #101713 49%, #10131c 100%); }
:global(html.dark .benchmark-board) { background: #0b1712; box-shadow: 0 28px 64px rgba(0, 0, 0, 0.32); }
@media (max-width: 1320px) {
@media (max-width: 1680px) {
.home-stage { grid-template-columns: 1fr; min-height: auto; }
.hero-copy { max-width: 800px; padding-top: 26px; }
.hero-copy h1 { white-space: normal; }
.capability-map { max-width: 850px; }
.map-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hero-copy h1 { white-space: pre-wrap; }
.ecosystem-map { max-width: 850px; }
}
@media (max-width: 1320px) {
.benchmark-section, .traffic-section { grid-template-columns: 1fr; min-height: auto; }
.benchmark-intro, .traffic-heading { max-width: 720px; }
.traffic-window { width: 100%; max-width: 1000px; }
@ -393,8 +491,6 @@ onMounted(async () => {
.hero-copy h1 { font-size: clamp(43px, 13vw, 62px); }
.hero-lead { font-size: 16px; }
.map-heading strong { white-space: normal; }
.map-grid { grid-template-columns: 1fr; }
.capability-card { min-height: 96px; }
.section-heading { grid-template-columns: 1fr; gap: 18px; }
.product-grid { grid-template-columns: 1fr; }
.product-card { min-height: 280px; }
@ -407,4 +503,20 @@ onMounted(async () => {
.pi-score b { grid-column: 2; }
.traffic-window { height: 660px; min-height: 0; border-radius: 17px; }
}
@media (max-width: 520px) {
.ecosystem-network { grid-template-columns: minmax(0, 1.1fr) 62px minmax(0, 1fr); gap: 4px; }
.network-group-label { flex-wrap: wrap; }
.brand-link strong, .capability-link strong { font-size: 10px; }
.network-ring { width: 78px; height: 78px; }
.network-core { width: 52px; height: 52px; }
.network-core img { width: 34px; height: 34px; }
.capability-link { gap: 3px; padding: 5px; }
.capability-link span:first-child { width: 22px; height: 22px; font-size: 13px; }
.backend-links { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
.brand-viewport { height: auto; mask-image: none; }
.brand-reel, .network-ring { animation: none; }
.reel-clone { display: none; }
}
</style>

View file

@ -111,8 +111,7 @@ It combines three kinds of capability:
| `embedding_store` | Disabled | When enabled, generate embeddings for chunks and support vector recall. |
Out of the box, search therefore uses primarily BM25 plus link expansion. After setting `embedding_store: default`,
`SearchStep` runs vector and keyword recall together. Additionally, switching the `file_store` `backend` from `local` to
`faiss` upgrades vector retrieval from a linear scan to a FAISS HNSW index, offering faster recall at scale.
`SearchStep` runs vector and keyword recall together.
The embedding store accepts `health_check_timeout` for its startup probe. A temporary failure skips the current vector
backfill while keeping BM25 available; a later successful provider request resumes the missing-vector backfill
@ -125,6 +124,17 @@ Use `scope: bm25` to rebuild only keyword search, or `scope: tag` to rebuild the
file graph. `scope: all` rebuilds BM25 first, then embeddings, and finally tags. BM25 and embedding rebuilds use the
current `file_chunks` snapshot; the tag rebuild uses `FileNode` frontmatter from the file graph.
## Vector Index Backends
With embeddings enabled, `file_store.default.backend` can be `local`, `zvec`, or `faiss`. `local` scans vectors linearly;
`zvec` uses an in-process HNSW index with native vector updates and deletes; `faiss` uses a FAISS HNSW index. The latter
two store rebuildable vector indexes. Memory files and ReMe's chunk data remain the source of truth.
To use Zvec or FAISS, first configure `as_embedding` and `embedding_store` as shown in
[Configuration](./configuration.md#embeddings). Then set `file_store.default.embedding_store` to `default` and
`file_store.default.backend` to `zvec` or `faiss`. The `core` installation includes both dependencies; the default
configuration still uses `local` with embeddings disabled.
## How to Search
The `search` Job is also configured in `default.yaml`:

View file

@ -102,8 +102,7 @@ file_store:
| `file_graph.default` | 启用 | 保存 `FileNode` 和 wikilink 边 |
| `embedding_store` | 默认关闭 | 开启后为 chunk 生成 embedding,并支持向量召回 |
所以开箱搜索主要是 BM25 + 链接展开。把 `embedding_store: default` 打开后,`SearchStep` 会同时跑向量召回和关键词召回。此时若将
`file_store` 的 `backend` 从 `local` 改为 `faiss`,向量检索会从线性扫描升级为 FAISS HNSW 索引,在大规模 chunk 场景下召回效率更高。
所以开箱搜索主要是 BM25 + 链接展开。把 `embedding_store: default` 打开后,`SearchStep` 会同时跑向量召回和关键词召回。
Embedding store 可通过 `health_check_timeout` 配置启动探测。临时失败只会跳过本次向量回填,BM25 仍可使用;
后续真实请求成功后会自动恢复缺失向量的回填。
@ -114,6 +113,16 @@ Embedding store 可通过 `health_check_timeout` 配置启动探测。临时失
BM25、Embedding 和标签索引。BM25 和 Embedding 使用当前的 `file_chunks` 快照,标签索引使用文件图中
`FileNode` 的 frontmatter。
## 向量索引后端
启用 Embedding 后,`file_store.default.backend` 可选择 `local`、`zvec` 或 `faiss`。`local` 线性扫描向量;
`zvec` 使用进程内 HNSW 索引,并原生更新、删除向量;`faiss` 使用 FAISS HNSW 索引。后两者都保存可重建的
向量索引,记忆文件和 ReMe 的 chunk 数据仍是事实来源。
要使用 Zvec 或 FAISS,在[基础配置](./configuration.md#embedding-配置)中先配置 `as_embedding` 和
`embedding_store`,再将 `file_store.default.embedding_store` 设为 `default`,并把
`file_store.default.backend` 设为 `zvec` 或 `faiss`。`core` 安装包含相应依赖;默认配置仍使用 `local`,且不启用 Embedding。
## 怎么搜索
`search` Job 也是在 `default.yaml` 中配置:

View file

@ -0,0 +1,13 @@
# Homepage ecosystem marks
The marks in `public/ecosystem/` identify linked projects on the homepage. Sources:
| File | Source |
| --- | --- |
| `qwenpaw.png` | [QwenPaw app icon](https://github.com/agentscope-ai/QwenPaw/blob/main/console/src-tauri/icons/icon.png) |
| `deepseek-harness.svg` | [DeepSeek Harness favicon](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/web/public/favicon.svg) |
| `openclaw.svg` | [OpenClaw app icon](https://github.com/openclaw/openclaw/blob/main/apps/linux/src-tauri/icons/icon.svg) |
| `claude-code.png` | [Claude site favicon](https://claude.com/) |
| `hermes.svg` | [Hermes favicon](https://github.com/NousResearch/hermes-agent/blob/main/website/static/img/favicon.svg) |
| `zvec.ico` | [Zvec site favicon](https://zvec.org/favicon.ico) |
| `faiss.png` | [Meta's facebookresearch organization avatar](https://github.com/facebookresearch), shown with the FAISS name because the FAISS repository has no project icon. |

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50.000000" height="50.000000" viewBox="0 0 50 50" fill="none">
<path id="path" d="M48.8354 10.0479C48.3232 9.79199 48.1025 10.2798 47.8032 10.5278C47.7007 10.6079 47.6143 10.7119 47.5273 10.8076C46.7793 11.624 45.9048 12.1597 44.7622 12.0957C43.0923 12 41.666 12.5356 40.4058 13.8398C40.1377 12.2319 39.2476 11.272 37.8926 10.6558C37.1836 10.3359 36.4668 10.0156 35.9702 9.31982C35.6235 8.82373 35.5293 8.27197 35.356 7.72754C35.2456 7.3999 35.1353 7.06396 34.7651 7.00781C34.3633 6.94385 34.2056 7.2876 34.0479 7.57568C33.418 8.75195 33.1733 10.0479 33.1973 11.3599C33.2524 14.312 34.4736 16.6641 36.8999 18.3359C37.1758 18.5278 37.2466 18.7197 37.1597 19C36.9946 19.5757 36.7974 20.1357 36.624 20.7119C36.5137 21.0801 36.3486 21.1597 35.9624 21C34.6309 20.4321 33.481 19.5918 32.4644 18.5757C30.7393 16.8721 29.1792 14.9917 27.2334 13.52C26.7764 13.1758 26.3193 12.856 25.8467 12.5518C23.8618 10.584 26.1069 8.96777 26.627 8.77588C27.1704 8.57568 26.8159 7.8877 25.0591 7.896C23.3022 7.90381 21.6953 8.50391 19.647 9.30371C19.3477 9.42383 19.0322 9.51172 18.7095 9.58398C16.8501 9.22363 14.9199 9.14355 12.9033 9.37598C9.10596 9.80762 6.07275 11.6396 3.84326 14.7681C1.16455 18.5278 0.53418 22.7998 1.30664 27.2559C2.11768 31.9521 4.46582 35.8398 8.07373 38.8799C11.8159 42.0322 16.1255 43.5762 21.041 43.2803C24.0269 43.104 27.3516 42.6963 31.1016 39.4561C32.0469 39.936 33.0396 40.1279 34.686 40.272C35.9546 40.3921 37.1758 40.208 38.1211 40.0078C39.6021 39.688 39.4995 38.2881 38.9639 38.0322C34.623 35.9678 35.5762 36.8081 34.71 36.1279C36.9155 33.4639 40.2402 30.6958 41.54 21.728C41.6426 21.0161 41.5557 20.5679 41.54 19.9917C41.5322 19.6396 41.6108 19.5039 42.0049 19.4639C43.0923 19.3359 44.1479 19.0317 45.1167 18.4878C47.9292 16.9199 49.064 14.3438 49.3315 11.2559C49.3711 10.7837 49.3237 10.2959 48.8354 10.0479ZM24.3262 37.8398C20.1196 34.4639 18.0791 33.3521 17.2358 33.3999C16.4482 33.4482 16.5898 34.3682 16.7632 34.9678C16.9443 35.5601 17.1812 35.9683 17.5117 36.4878C17.7402 36.832 17.8979 37.3442 17.2832 37.728C15.9282 38.584 13.5728 37.4399 13.4624 37.3838C10.7207 35.7358 8.42822 33.5601 6.81348 30.584C5.25342 27.7197 4.34766 24.6479 4.19775 21.3677C4.1582 20.5757 4.38672 20.2959 5.15869 20.1519C6.17529 19.96 7.22314 19.9199 8.23926 20.0718C12.5327 20.7119 16.1885 22.6719 19.2529 25.7759C21.002 27.5439 22.3252 29.6558 23.6885 31.7202C25.1377 33.9121 26.6978 36 28.6831 37.7119C29.3843 38.312 29.9434 38.7681 30.479 39.104C28.8643 39.2881 26.1699 39.3281 24.3262 37.8398ZM26.3433 24.6001C26.3433 24.248 26.6191 23.9678 26.9658 23.9678C27.0444 23.9678 27.1152 23.9839 27.1782 24.0078C27.2651 24.04 27.3438 24.0879 27.4067 24.1602C27.5171 24.272 27.5801 24.4321 27.5801 24.6001C27.5801 24.9521 27.3042 25.2319 26.9575 25.2319C26.6108 25.2319 26.3433 24.9521 26.3433 24.6001ZM32.6064 27.8799C32.2046 28.0479 31.8027 28.1919 31.4165 28.208C30.8179 28.2397 30.1641 27.9922 29.8096 27.688C29.2583 27.2158 28.8643 26.9521 28.6987 26.1279C28.6279 25.7759 28.6675 25.2319 28.7305 24.9199C28.8721 24.248 28.7144 23.8159 28.2495 23.4238C27.8716 23.104 27.3911 23.0161 26.8633 23.0161C26.666 23.0161 26.4849 22.9277 26.3511 22.856C26.1304 22.7441 25.9492 22.4639 26.1226 22.1201C26.1777 22.0078 26.4458 21.7358 26.5088 21.688C27.2256 21.272 28.0527 21.4077 28.8169 21.7197C29.5259 22.0161 30.0615 22.5601 30.834 23.3281C31.6216 24.2559 31.7632 24.5117 32.2124 25.208C32.5669 25.752 32.8901 26.312 33.1104 26.9521C33.2446 27.3521 33.0713 27.6802 32.6064 27.8799Z" fill="#000" fill-opacity="1.000000" fill-rule="nonzero"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<text y=".9em" font-size="90">☤</text>
</svg>

After

Width:  |  Height:  |  Size: 113 B

View file

@ -0,0 +1,18 @@
<svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="lobster-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ff4d4d"/>
<stop offset="100%" stop-color="#991b1b"/>
</linearGradient>
</defs>
<!-- OpenClaw mascot (static): the Clawd lobster, mirroring ui/public/favicon.svg base pose. -->
<path d="M60 10 C30 10 15 35 15 55 C15 75 30 95 45 100 L45 110 L55 110 L55 100 C55 100 60 102 65 100 L65 110 L75 110 L75 100 C90 95 105 75 105 55 C105 35 90 10 60 10Z" fill="url(#lobster-gradient)"/>
<path d="M20 45 C5 40 0 50 5 60 C10 70 20 65 25 55 C28 48 25 45 20 45Z" fill="url(#lobster-gradient)"/>
<path d="M100 45 C115 40 120 50 115 60 C110 70 100 65 95 55 C92 48 95 45 100 45Z" fill="url(#lobster-gradient)"/>
<path d="M45 15 Q35 5 30 8" stroke="#ff4d4d" stroke-width="3" stroke-linecap="round"/>
<path d="M75 15 Q85 5 90 8" stroke="#ff4d4d" stroke-width="3" stroke-linecap="round"/>
<circle cx="45" cy="35" r="6" fill="#050810"/>
<circle cx="75" cy="35" r="6" fill="#050810"/>
<circle cx="46" cy="34" r="2.5" fill="#00e5cc"/>
<circle cx="76" cy="34" r="2.5" fill="#00e5cc"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -215,6 +215,9 @@ await cp(path.join(repoDir, "docs"), outputDir, {
filter: (source) => ![".DS_Store", "plans"].includes(path.basename(source)),
});
await cp(path.join(siteDir, "public", "CNAME"), path.join(outputDir, "public", "CNAME"));
await cp(path.join(siteDir, "public", "ecosystem"), path.join(outputDir, "public", "ecosystem"), {
recursive: true,
});
await cp(path.join(repoDir, "docs/figure/reme-icon.svg"), path.join(outputDir, "public", "reme-icon.svg"));
await cp(path.join(repoDir, "docs/figure/reme-logo-fashion.svg"), path.join(outputDir, "public", "reme-logo.svg"));

View file

@ -35,6 +35,13 @@ const requiredFiles = [
"CNAME",
"reme-icon.svg",
"reme-logo.svg",
"ecosystem/qwenpaw.png",
"ecosystem/deepseek-harness.svg",
"ecosystem/openclaw.svg",
"ecosystem/claude-code.png",
"ecosystem/hermes.svg",
"ecosystem/zvec.ico",
"ecosystem/faiss.png",
"hashmap.json",
"sitemap.xml",
"llms.txt",

View file

@ -35,6 +35,9 @@ test("generates every required bilingual guide", async () => {
await access(path.join(generatedDir, "en/integrations/openclaw.md"));
await access(path.join(generatedDir, "public/figures/dsh/reme-status-overview.png"));
await access(path.join(generatedDir, "public/figures/studio/studio-overview.png"));
for (const name of ["qwenpaw.png", "deepseek-harness.svg", "openclaw.svg", "claude-code.png", "hermes.svg", "zvec.ico", "faiss.png"]) {
await access(path.join(generatedDir, "public/ecosystem", name));
}
});
test("maps mirrored pages back to their canonical repository sources", async () => {