mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-08-28 05:25:04 +00:00
docs: add standalone GitHub Pages site (#448)
This commit is contained in:
parent
ab66f2bb56
commit
52fdd446fb
19 changed files with 2036 additions and 11 deletions
64
.github/workflows/pages.yml
vendored
Normal file
64
.github/workflows/pages.yml
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
name: Deploy ReMe documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "github-pages/**"
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "README_ZH.md"
|
||||
- "skills/reme_memory/SKILL.md"
|
||||
- "AGENTS.md"
|
||||
- ".github/workflows/pages.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "22.13"
|
||||
cache: npm
|
||||
cache-dependency-path: github-pages/package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: github-pages
|
||||
run: npm ci
|
||||
|
||||
- name: Build documentation
|
||||
working-directory: github-pages
|
||||
run: npm run build
|
||||
|
||||
- name: Configure Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload Pages artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: github-pages/dist
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<a href="https://pepy.tech/project/reme-ai/"><img src="https://img.shields.io/pypi/dm/reme-ai" alt="PyPI Downloads"></a>
|
||||
<a href="https://github.com/agentscope-ai/ReMe"><img src="https://img.shields.io/github/commit-activity/m/agentscope-ai/ReMe?style=flat-square" alt="GitHub commit activity"></a>
|
||||
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-black" alt="License"></a>
|
||||
<a href="https://docs.agentscope.io/reme"><img src="https://img.shields.io/badge/docs-ReMe-blue" alt="Documentation"></a>
|
||||
<a href="https://reme.agentscope.io"><img src="https://img.shields.io/badge/docs-ReMe-blue" alt="Documentation"></a>
|
||||
<a href="./README.md"><img src="https://img.shields.io/badge/English-Click-yellow" alt="English"></a>
|
||||
<a href="./README_ZH.md"><img src="https://img.shields.io/badge/简体中文-点击查看-orange" alt="简体中文"></a>
|
||||
<a href="https://github.com/agentscope-ai/ReMe"><img src="https://img.shields.io/github/stars/agentscope-ai/ReMe?style=social" alt="GitHub Stars"></a>
|
||||
|
|
@ -422,7 +422,7 @@ are mainly for maintenance, debugging, or advanced integration. Run `reme help`
|
|||
- **Pre-submit checks**: Before submitting a PR, try to run `pre-commit run --all-files` and `pytest`. If tests that
|
||||
depend on LLMs, embeddings, or external services cannot run, explain that in the PR.
|
||||
- **Get help**: Use [GitHub Issues](https://github.com/agentscope-ai/ReMe/issues) for bugs and feature requests. Project
|
||||
documentation is available at [https://docs.agentscope.io/reme](https://docs.agentscope.io/reme).
|
||||
documentation is available at [https://reme.agentscope.io](https://reme.agentscope.io).
|
||||
|
||||
### Contributors
|
||||
|
||||
|
|
@ -438,7 +438,7 @@ Thanks to everyone who has contributed to ReMe:
|
|||
@software{ReMe2026,
|
||||
title = {Remember me, Refine me: Memory Management Kit for Agents},
|
||||
author = {ReMe Team},
|
||||
url = {https://docs.agentscope.io/reme},
|
||||
url = {https://reme.agentscope.io},
|
||||
year = {2026}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<a href="https://pepy.tech/project/reme-ai/"><img src="https://img.shields.io/pypi/dm/reme-ai" alt="PyPI Downloads"></a>
|
||||
<a href="https://github.com/agentscope-ai/ReMe"><img src="https://img.shields.io/github/commit-activity/m/agentscope-ai/ReMe?style=flat-square" alt="GitHub commit activity"></a>
|
||||
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-black" alt="License"></a>
|
||||
<a href="https://docs.agentscope.io/reme"><img src="https://img.shields.io/badge/docs-ReMe-blue" alt="文档"></a>
|
||||
<a href="https://reme.agentscope.io"><img src="https://img.shields.io/badge/docs-ReMe-blue" alt="文档"></a>
|
||||
<a href="./README.md"><img src="https://img.shields.io/badge/English-Click-yellow" alt="English"></a>
|
||||
<a href="./README_ZH.md"><img src="https://img.shields.io/badge/简体中文-点击查看-orange" alt="简体中文"></a>
|
||||
<a href="https://github.com/agentscope-ai/ReMe"><img src="https://img.shields.io/github/stars/agentscope-ai/ReMe?style=social" alt="GitHub Stars"></a>
|
||||
|
|
@ -398,7 +398,7 @@ frontmatter 和文件操作接口主要用于维护、调试或高级集成。
|
|||
- **提交前检查**:提交 PR 前请尽量运行 `pre-commit run --all-files` 和 `pytest`;如有依赖 LLM、embedding 或外部服务的测试无法运行,请在
|
||||
PR 中说明。
|
||||
- **获取帮助**:如需反馈 Bug 或功能请求,请使用 [GitHub Issues](https://github.com/agentscope-ai/ReMe/issues);项目文档见
|
||||
[https://docs.agentscope.io/reme](https://docs.agentscope.io/reme)。
|
||||
[https://reme.agentscope.io](https://reme.agentscope.io)。
|
||||
|
||||
### 贡献者
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ frontmatter 和文件操作接口主要用于维护、调试或高级集成。
|
|||
@software{ReMe2026,
|
||||
title = {Remember me, Refine me: Memory Management Kit for Agents},
|
||||
author = {ReMe Team},
|
||||
url = {https://docs.agentscope.io/reme},
|
||||
url = {https://reme.agentscope.io},
|
||||
year = {2026}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ Documentation should:
|
|||
|
||||
- Bugs and feature requests: [GitHub Issues](https://github.com/agentscope-ai/ReMe/issues)
|
||||
- Project home: [GitHub Repository](https://github.com/agentscope-ai/ReMe)
|
||||
- Documentation site: [https://docs.agentscope.io/reme](https://docs.agentscope.io/reme)
|
||||
- Documentation site: [https://reme.agentscope.io](https://reme.agentscope.io)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ That is exactly what ReMe sets out to do.
|
|||
|
||||
GitHub: [https://github.com/agentscope-ai/ReMe](https://github.com/agentscope-ai/ReMe)
|
||||
|
||||
Documentation: [https://docs.agentscope.io/reme](https://docs.agentscope.io/reme)
|
||||
Documentation: [https://reme.agentscope.io](https://reme.agentscope.io)
|
||||
|
||||
<p align="center">
|
||||
<img src="../figure/reme-blog/reme-blog-cover-benchmark.png" alt="ReMe self-evolving personal knowledge base and public benchmark results" width="100%">
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ docs/
|
|||
|
||||
- Bugs 和功能请求:[GitHub Issues](https://github.com/agentscope-ai/ReMe/issues)
|
||||
- 项目主页:[GitHub Repository](https://github.com/agentscope-ai/ReMe)
|
||||
- 文档站点:[https://docs.agentscope.io/reme](https://docs.agentscope.io/reme)
|
||||
- 文档站点:[https://reme.agentscope.io](https://reme.agentscope.io)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Markdown 记忆,并从中提炼值得继续关注的线索。**
|
|||
|
||||
项目地址:[https://github.com/agentscope-ai/ReMe](https://github.com/agentscope-ai/ReMe)
|
||||
|
||||
项目文档:[https://docs.agentscope.io/reme](https://docs.agentscope.io/reme)
|
||||
项目文档:[https://reme.agentscope.io](https://reme.agentscope.io)
|
||||
|
||||
<p align="center">
|
||||
<img src="../figure/reme-blog/reme-blog-cover-benchmark.png" alt="ReMe 自进化个人知识库与公开基准结果" width="100%">
|
||||
|
|
|
|||
3
github-pages/.gitignore
vendored
Normal file
3
github-pages/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
node_modules/
|
||||
dist/
|
||||
.generated/
|
||||
86
github-pages/README.md
Normal file
86
github-pages/README.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# ReMe GitHub Pages
|
||||
|
||||
This directory contains the standalone Vite documentation site published at <https://reme.agentscope.io>. The
|
||||
GitHub Pages fallback is <https://agentscope-ai.github.io/ReMe/>. It does not depend on the ReMe Studio application in
|
||||
`website/`.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 22.13 or newer
|
||||
- npm
|
||||
|
||||
## Local development
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
cd github-pages
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open the URL printed by Vite, normally <http://localhost:5173/>. The development server watches the frontend source.
|
||||
When a repository Markdown file changes, restart the development command to regenerate the documentation content.
|
||||
|
||||
For subsequent installs or CI-compatible dependency installation, use:
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
```
|
||||
|
||||
## Preview the production build
|
||||
|
||||
Build and start the preview server:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm run preview
|
||||
```
|
||||
|
||||
Open the URL printed by Vite, normally <http://localhost:4173/>. Production assets use relative paths so the same build
|
||||
works on both the custom domain and the GitHub Pages project path.
|
||||
|
||||
The generated `dist/` and `.generated/` directories are disposable build output and are excluded from Git.
|
||||
|
||||
## Documentation sources
|
||||
|
||||
The build script reads the canonical repository files directly. Do not edit generated copies under `.generated/` or
|
||||
`dist/`.
|
||||
|
||||
- `README.md` and `README_ZH.md`: project introductions
|
||||
- `docs/en/` and `docs/zh/`: English and Chinese guides
|
||||
- `docs/figure/`: documentation images
|
||||
- `skills/reme_memory/SKILL.md`: ReMe Memory skill guide
|
||||
- `AGENTS.md`: repository development guide
|
||||
|
||||
To add or reorganize a document in the site navigation, update
|
||||
[`scripts/generate-content.mjs`](./scripts/generate-content.mjs). Presentation and interaction code lives in `src/`.
|
||||
|
||||
## Project structure
|
||||
|
||||
```text
|
||||
github-pages/
|
||||
├── index.html
|
||||
├── package.json
|
||||
├── scripts/
|
||||
│ └── generate-content.mjs
|
||||
├── src/
|
||||
│ ├── main.js
|
||||
│ └── styles.css
|
||||
└── vite.config.js
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
The repository workflow `.github/workflows/pages.yml` builds this directory and publishes `dist/` to GitHub Pages.
|
||||
It runs after relevant documentation or site files change on `main`, and it can also be started manually from the
|
||||
GitHub Actions page.
|
||||
|
||||
The repository's **Settings → Pages → Build and deployment → Source** must be set to **GitHub Actions**. Its custom
|
||||
domain must be set to `reme.agentscope.io`; `public/CNAME` preserves that domain in the published artifact.
|
||||
|
||||
Useful links:
|
||||
|
||||
- ReMe documentation: <https://reme.agentscope.io>
|
||||
- GitHub Pages fallback: <https://agentscope-ai.github.io/ReMe/>
|
||||
- ReMe repository: <https://github.com/agentscope-ai/ReMe>
|
||||
17
github-pages/index.html
Normal file
17
github-pages/index.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="ReMe documentation — a local-first, file-native memory system for agents."
|
||||
/>
|
||||
<link rel="icon" type="image/svg+xml" href="%BASE_URL%favicon.svg" />
|
||||
<title>ReMe Documentation</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1157
github-pages/package-lock.json
generated
Normal file
1157
github-pages/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
21
github-pages/package.json
Normal file
21
github-pages/package.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "reme-github-pages",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=22.13.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "node scripts/generate-content.mjs && vite",
|
||||
"build": "node scripts/generate-content.mjs && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"dompurify": "^3.2.6",
|
||||
"marked": "^16.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^7.1.1"
|
||||
}
|
||||
}
|
||||
1
github-pages/public/CNAME
Normal file
1
github-pages/public/CNAME
Normal file
|
|
@ -0,0 +1 @@
|
|||
reme.agentscope.io
|
||||
19
github-pages/public/favicon.svg
Normal file
19
github-pages/public/favicon.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<title>ReMe Documentation</title>
|
||||
<defs>
|
||||
<linearGradient id="reme-gradient" x1="8" y1="6" x2="56" y2="58" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#19c9b0"/>
|
||||
<stop offset="1" stop-color="#3156d9"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="64" height="64" rx="19" fill="url(#reme-gradient)"/>
|
||||
<text
|
||||
x="32"
|
||||
y="44"
|
||||
fill="#ffffff"
|
||||
font-family="Georgia, 'Times New Roman', serif"
|
||||
font-size="39"
|
||||
font-weight="700"
|
||||
text-anchor="middle"
|
||||
>R</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 574 B |
147
github-pages/scripts/generate-content.mjs
Normal file
147
github-pages/scripts/generate-content.mjs
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const siteDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const repoDir = path.resolve(siteDir, "..");
|
||||
const outputDir = path.join(siteDir, ".generated", "content");
|
||||
|
||||
const topicOrder = [
|
||||
"quick_start",
|
||||
"memory_as_file",
|
||||
"memory_search",
|
||||
"auto_memory",
|
||||
"auto_resource",
|
||||
"auto_link",
|
||||
"auto_dream",
|
||||
"proactive",
|
||||
"reme_scene",
|
||||
"framework",
|
||||
"reme-blog",
|
||||
"contributing",
|
||||
];
|
||||
|
||||
const groups = {
|
||||
quick_start: "start",
|
||||
memory_as_file: "fundamentals",
|
||||
memory_search: "fundamentals",
|
||||
auto_memory: "automation",
|
||||
auto_resource: "automation",
|
||||
auto_link: "automation",
|
||||
auto_dream: "automation",
|
||||
proactive: "automation",
|
||||
reme_scene: "concepts",
|
||||
framework: "concepts",
|
||||
"reme-blog": "concepts",
|
||||
contributing: "development",
|
||||
};
|
||||
|
||||
const localizedTitles = {
|
||||
quick_start: { zh: "快速开始", en: "Quick Start" },
|
||||
memory_as_file: { zh: "文件即记忆", en: "Memory as File" },
|
||||
memory_search: { zh: "记忆检索", en: "Memory Search" },
|
||||
auto_memory: { zh: "自动记忆", en: "Auto Memory" },
|
||||
auto_resource: { zh: "自动资料整理", en: "Auto Resource" },
|
||||
auto_link: { zh: "自动关联", en: "Auto Link" },
|
||||
auto_dream: { zh: "自动沉淀", en: "Auto Dream" },
|
||||
proactive: { zh: "主动发现", en: "Proactive" },
|
||||
reme_scene: { zh: "ReMe 应用场景", en: "ReMe Application Scenarios" },
|
||||
framework: { zh: "ReMe 代码框架", en: "ReMe Framework" },
|
||||
"reme-blog": { zh: "ReMe 博客", en: "ReMe Blog" },
|
||||
contributing: { zh: "开源与贡献", en: "Open Source and Contributing" },
|
||||
};
|
||||
|
||||
const sharedDocuments = [
|
||||
{
|
||||
id: "reme-memory-skill",
|
||||
path: "skills/reme_memory/SKILL.md",
|
||||
sourcePath: "skills/reme_memory/SKILL.md",
|
||||
titles: {
|
||||
zh: "ReMe 记忆技能",
|
||||
en: "ReMe Memory Skill",
|
||||
},
|
||||
description: "Bootstrap, retrieve, write, and consolidate memory from an agent.",
|
||||
group: "integration",
|
||||
language: "shared",
|
||||
},
|
||||
{
|
||||
id: "agents-guide",
|
||||
path: "AGENTS.md",
|
||||
sourcePath: "AGENTS.md",
|
||||
titles: {
|
||||
zh: "Agent 开发指南",
|
||||
en: "Agent Development Guide",
|
||||
},
|
||||
description: "Repository contracts, lifecycle rules, safety boundaries, and validation.",
|
||||
group: "development",
|
||||
language: "shared",
|
||||
},
|
||||
];
|
||||
|
||||
async function markdownTitle(filePath) {
|
||||
const source = await readFile(filePath, "utf8");
|
||||
return source.match(/^#\s+(.+)$/m)?.[1]?.replace(/[`*_]/g, "") || path.basename(filePath, ".md");
|
||||
}
|
||||
|
||||
async function buildManifest() {
|
||||
const documents = [
|
||||
{
|
||||
id: "readme-zh",
|
||||
path: "README_ZH.md",
|
||||
sourcePath: "README_ZH.md",
|
||||
title: "ReMe 项目介绍",
|
||||
description: "核心理念、快速开始、使用场景与社区入口。",
|
||||
group: "overview",
|
||||
language: "zh",
|
||||
},
|
||||
{
|
||||
id: "readme-en",
|
||||
path: "README.md",
|
||||
sourcePath: "README.md",
|
||||
title: "Introducing ReMe",
|
||||
description: "Core ideas, quick start, use cases, and community resources.",
|
||||
group: "overview",
|
||||
language: "en",
|
||||
},
|
||||
];
|
||||
|
||||
for (const language of ["zh", "en"]) {
|
||||
for (const topic of topicOrder) {
|
||||
const sourcePath = `docs/${language}/${topic}.md`;
|
||||
documents.push({
|
||||
id: `${language}-${topic}`,
|
||||
path: sourcePath,
|
||||
sourcePath,
|
||||
title: localizedTitles[topic]?.[language] || (await markdownTitle(path.join(repoDir, sourcePath))),
|
||||
description: "",
|
||||
group: groups[topic],
|
||||
language,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return [...documents, ...sharedDocuments];
|
||||
}
|
||||
|
||||
await rm(path.join(siteDir, ".generated"), { recursive: true, force: true });
|
||||
await mkdir(outputDir, { recursive: true });
|
||||
await cp(path.join(siteDir, "public", "favicon.svg"), path.join(siteDir, ".generated", "favicon.svg"));
|
||||
await cp(path.join(siteDir, "public", "CNAME"), path.join(siteDir, ".generated", "CNAME"));
|
||||
|
||||
for (const file of ["README.md", "README_ZH.md", "AGENTS.md"]) {
|
||||
await cp(path.join(repoDir, file), path.join(outputDir, file));
|
||||
}
|
||||
await cp(path.join(repoDir, "docs"), path.join(outputDir, "docs"), {
|
||||
recursive: true,
|
||||
filter: (source) => path.basename(source) !== ".DS_Store",
|
||||
});
|
||||
await mkdir(path.join(outputDir, "skills", "reme_memory"), { recursive: true });
|
||||
await cp(
|
||||
path.join(repoDir, "skills", "reme_memory", "SKILL.md"),
|
||||
path.join(outputDir, "skills", "reme_memory", "SKILL.md"),
|
||||
);
|
||||
|
||||
await writeFile(
|
||||
path.join(outputDir, "manifest.json"),
|
||||
`${JSON.stringify({ documents: await buildManifest() }, null, 2)}\n`,
|
||||
);
|
||||
340
github-pages/src/main.js
Normal file
340
github-pages/src/main.js
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
import DOMPurify from "dompurify";
|
||||
import { marked } from "marked";
|
||||
import "./styles.css";
|
||||
|
||||
const baseUrl = import.meta.env.BASE_URL;
|
||||
const repositoryUrl = "https://github.com/agentscope-ai/ReMe";
|
||||
const officialDocsUrl = "https://reme.agentscope.io";
|
||||
|
||||
const copy = {
|
||||
zh: {
|
||||
docs: "文档",
|
||||
search: "搜索文档…",
|
||||
noResults: "没有找到匹配的文档",
|
||||
menu: "打开导航",
|
||||
toc: "本页目录",
|
||||
edit: "在 GitHub 查看源文件",
|
||||
officialDocs: "官方文档",
|
||||
groups: {
|
||||
overview: "项目介绍",
|
||||
start: "开始使用",
|
||||
fundamentals: "核心原理",
|
||||
automation: "自动化能力",
|
||||
concepts: "架构与场景",
|
||||
integration: "Agent 集成",
|
||||
development: "开发者规范",
|
||||
},
|
||||
},
|
||||
en: {
|
||||
docs: "Documentation",
|
||||
search: "Search documentation…",
|
||||
noResults: "No matching documents",
|
||||
menu: "Open navigation",
|
||||
toc: "On this page",
|
||||
edit: "View source on GitHub",
|
||||
officialDocs: "Official docs",
|
||||
groups: {
|
||||
overview: "Introduction",
|
||||
start: "Get started",
|
||||
fundamentals: "Fundamentals",
|
||||
automation: "Automation",
|
||||
concepts: "Architecture & scenarios",
|
||||
integration: "Agent integration",
|
||||
development: "Development",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const state = {
|
||||
language: localStorage.getItem("reme-docs-language") || "zh",
|
||||
documents: [],
|
||||
activeDocument: null,
|
||||
query: "",
|
||||
};
|
||||
|
||||
const app = document.querySelector("#app");
|
||||
|
||||
app.innerHTML = `
|
||||
<header class="topbar">
|
||||
<a class="brand" href="${baseUrl}" aria-label="ReMe documentation home">
|
||||
<span class="brand-mark">R</span>
|
||||
<span>ReMe</span>
|
||||
<span class="brand-divider"></span>
|
||||
<span class="brand-section" data-copy="docs"></span>
|
||||
</a>
|
||||
<nav class="top-actions" aria-label="Global navigation">
|
||||
<div class="language-switch" role="group" aria-label="Language">
|
||||
<button type="button" data-language="zh">中</button>
|
||||
<button type="button" data-language="en">EN</button>
|
||||
</div>
|
||||
<a class="official-docs-link" href="${officialDocsUrl}" target="_blank" rel="noreferrer" data-copy="officialDocs"></a>
|
||||
<a class="github-link" href="${repositoryUrl}" target="_blank" rel="noreferrer">GitHub ↗</a>
|
||||
<button class="menu-button" type="button" aria-expanded="false" data-action="menu"></button>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="docs-shell">
|
||||
<aside class="sidebar" aria-label="Documentation navigation">
|
||||
<label class="search-box">
|
||||
<span aria-hidden="true">⌕</span>
|
||||
<input type="search" autocomplete="off" />
|
||||
<kbd>⌘K</kbd>
|
||||
</label>
|
||||
<nav class="document-nav"></nav>
|
||||
<div class="sidebar-footer">
|
||||
<span class="status-dot"></span>
|
||||
Local-first · File-native
|
||||
</div>
|
||||
</aside>
|
||||
<main class="article-wrap">
|
||||
<article class="article"><div class="loading-line"></div></article>
|
||||
</main>
|
||||
<aside class="toc-panel"><nav class="toc"></nav></aside>
|
||||
</div>
|
||||
<button class="sidebar-backdrop" type="button" aria-label="Close navigation"></button>
|
||||
`;
|
||||
|
||||
const sidebar = app.querySelector(".sidebar");
|
||||
const documentNav = app.querySelector(".document-nav");
|
||||
const article = app.querySelector(".article");
|
||||
const toc = app.querySelector(".toc");
|
||||
const searchInput = app.querySelector("input[type='search']");
|
||||
const menuButton = app.querySelector(".menu-button");
|
||||
const backdrop = app.querySelector(".sidebar-backdrop");
|
||||
|
||||
function slugify(value) {
|
||||
return value
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/<[^>]+>/g, "")
|
||||
.replace(/[^\p{Letter}\p{Number}]+/gu, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
function resolveDocumentPath(currentPath, target) {
|
||||
const cleanTarget = target.split("#")[0].split("?")[0];
|
||||
const currentParts = currentPath.split("/");
|
||||
currentParts.pop();
|
||||
for (const part of cleanTarget.split("/")) {
|
||||
if (!part || part === ".") continue;
|
||||
if (part === "..") currentParts.pop();
|
||||
else currentParts.push(part);
|
||||
}
|
||||
return currentParts.join("/");
|
||||
}
|
||||
|
||||
function configureMarkdown(document) {
|
||||
const renderer = new marked.Renderer();
|
||||
const headingIds = new Map();
|
||||
|
||||
renderer.heading = ({ tokens, depth }) => {
|
||||
const text = tokens.map((token) => token.text || token.raw || "").join("");
|
||||
const baseSlug = slugify(text) || "section";
|
||||
const count = headingIds.get(baseSlug) || 0;
|
||||
headingIds.set(baseSlug, count + 1);
|
||||
const id = count ? `${baseSlug}-${count + 1}` : baseSlug;
|
||||
return `<h${depth} id="${id}">${text}</h${depth}>`;
|
||||
};
|
||||
|
||||
renderer.image = ({ href, title, text }) => {
|
||||
const url = /^(https?:|data:)/.test(href)
|
||||
? href
|
||||
: `${baseUrl}content/${resolveDocumentPath(document.path, href)}`;
|
||||
const titleAttribute = title ? ` title="${title}"` : "";
|
||||
return `<img src="${url}" alt="${text}" loading="lazy"${titleAttribute}>`;
|
||||
};
|
||||
|
||||
renderer.link = ({ href, title, tokens }) => {
|
||||
const label = tokens.map((token) => token.text || token.raw || "").join("");
|
||||
const titleAttribute = title ? ` title="${title}"` : "";
|
||||
if (href.startsWith("#")) return `<a href="${href}"${titleAttribute}>${label}</a>`;
|
||||
if (!/^(https?:|mailto:)/.test(href)) {
|
||||
const resolved = resolveDocumentPath(document.path, href);
|
||||
const localDocument = state.documents.find((item) => item.path === resolved);
|
||||
if (localDocument) return `<a href="?doc=${localDocument.id}" data-doc="${localDocument.id}">${label}</a>`;
|
||||
return `<a href="${repositoryUrl}/blob/main/${resolved}" target="_blank" rel="noreferrer">${label}</a>`;
|
||||
}
|
||||
return `<a href="${href}" target="_blank" rel="noreferrer"${titleAttribute}>${label}</a>`;
|
||||
};
|
||||
|
||||
marked.use({ renderer, gfm: true, breaks: false });
|
||||
}
|
||||
|
||||
function availableDocuments() {
|
||||
return state.documents.filter(
|
||||
(document) => document.language === state.language || document.language === "shared",
|
||||
);
|
||||
}
|
||||
|
||||
function documentTitle(document) {
|
||||
return document.titles?.[state.language] || document.title;
|
||||
}
|
||||
|
||||
function renderChrome() {
|
||||
const labels = copy[state.language];
|
||||
app.querySelector("[data-copy='docs']").textContent = labels.docs;
|
||||
app.querySelector("[data-copy='officialDocs']").textContent = `${labels.officialDocs} ↗`;
|
||||
searchInput.placeholder = labels.search;
|
||||
menuButton.textContent = labels.menu;
|
||||
document.documentElement.lang = state.language === "zh" ? "zh-CN" : "en";
|
||||
app.querySelectorAll("[data-language]").forEach((button) => {
|
||||
button.classList.toggle("active", button.dataset.language === state.language);
|
||||
});
|
||||
}
|
||||
|
||||
function renderNavigation() {
|
||||
const labels = copy[state.language];
|
||||
const query = state.query.trim().toLocaleLowerCase();
|
||||
const filtered = availableDocuments().filter((document) =>
|
||||
`${documentTitle(document)} ${document.title || ""} ${document.description}`.toLocaleLowerCase().includes(query),
|
||||
);
|
||||
const groups = [...new Set(filtered.map((document) => document.group))];
|
||||
|
||||
if (!filtered.length) {
|
||||
documentNav.innerHTML = `<p class="empty-state">${labels.noResults}</p>`;
|
||||
return;
|
||||
}
|
||||
|
||||
documentNav.innerHTML = groups
|
||||
.map(
|
||||
(group) => `
|
||||
<section class="nav-group">
|
||||
<h2>${labels.groups[group]}</h2>
|
||||
${filtered
|
||||
.filter((document) => document.group === group)
|
||||
.map(
|
||||
(document) => `
|
||||
<a href="?doc=${document.id}" data-doc="${document.id}" class="${state.activeDocument?.id === document.id ? "active" : ""}">
|
||||
<span>${documentTitle(document)}</span>
|
||||
</a>`,
|
||||
)
|
||||
.join("")}
|
||||
</section>`,
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
function renderToc() {
|
||||
const headings = [...article.querySelectorAll("h2, h3")];
|
||||
if (!headings.length) {
|
||||
toc.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
toc.innerHTML = `
|
||||
<h2>${copy[state.language].toc}</h2>
|
||||
${headings
|
||||
.map(
|
||||
(heading) => `<a class="toc-${heading.tagName.toLowerCase()}" href="#${heading.id}">${heading.childNodes[0]?.textContent || heading.textContent}</a>`,
|
||||
)
|
||||
.join("")}
|
||||
`;
|
||||
}
|
||||
|
||||
function rewriteRenderedUrls(document) {
|
||||
article.querySelectorAll("img[src]").forEach((image) => {
|
||||
const source = image.getAttribute("src");
|
||||
if (source && !/^(https?:|data:|\/)/.test(source)) {
|
||||
image.src = `${baseUrl}content/${resolveDocumentPath(document.path, source)}`;
|
||||
}
|
||||
});
|
||||
|
||||
article.querySelectorAll("a[href]").forEach((link) => {
|
||||
const href = link.getAttribute("href");
|
||||
if (!href || /^(https?:|mailto:|#|\/)/.test(href) || link.dataset.doc) return;
|
||||
const resolved = resolveDocumentPath(document.path, href);
|
||||
const localDocument = state.documents.find((item) => item.path === resolved);
|
||||
if (localDocument) {
|
||||
link.href = `?doc=${localDocument.id}`;
|
||||
link.dataset.doc = localDocument.id;
|
||||
link.removeAttribute("target");
|
||||
return;
|
||||
}
|
||||
link.href = `${repositoryUrl}/blob/main/${resolved}`;
|
||||
link.target = "_blank";
|
||||
link.rel = "noreferrer";
|
||||
});
|
||||
}
|
||||
|
||||
async function openDocument(id, pushHistory = true) {
|
||||
const fallbackId = state.language === "zh" ? "readme-zh" : "readme-en";
|
||||
const document = state.documents.find((item) => item.id === id) || state.documents.find((item) => item.id === fallbackId);
|
||||
state.activeDocument = document;
|
||||
article.dataset.group = document.group;
|
||||
renderNavigation();
|
||||
article.innerHTML = `<div class="loading-line"></div>`;
|
||||
|
||||
const response = await fetch(`${baseUrl}content/${document.path}`);
|
||||
if (!response.ok) throw new Error(`Unable to load ${document.path}`);
|
||||
configureMarkdown(document);
|
||||
const markdown = await response.text();
|
||||
const body = DOMPurify.sanitize(await marked.parse(markdown), {
|
||||
ADD_ATTR: ["target"],
|
||||
});
|
||||
article.innerHTML = `
|
||||
<div class="article-meta">
|
||||
<span>${copy[state.language].groups[document.group]}</span>
|
||||
<span>·</span>
|
||||
<span>${document.sourcePath}</span>
|
||||
</div>
|
||||
<div class="markdown-body">${body}</div>
|
||||
<footer class="article-footer">
|
||||
<a href="${repositoryUrl}/blob/main/${document.sourcePath}" target="_blank" rel="noreferrer">${copy[state.language].edit} ↗</a>
|
||||
</footer>
|
||||
`;
|
||||
rewriteRenderedUrls(document);
|
||||
renderToc();
|
||||
closeMenu();
|
||||
if (pushHistory) history.pushState({ doc: document.id }, "", `?doc=${document.id}`);
|
||||
window.scrollTo({ top: 0, behavior: "instant" });
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
sidebar.classList.remove("open");
|
||||
backdrop.classList.remove("visible");
|
||||
menuButton.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
|
||||
function toggleMenu() {
|
||||
const open = !sidebar.classList.contains("open");
|
||||
sidebar.classList.toggle("open", open);
|
||||
backdrop.classList.toggle("visible", open);
|
||||
menuButton.setAttribute("aria-expanded", String(open));
|
||||
}
|
||||
|
||||
app.addEventListener("click", (event) => {
|
||||
const documentLink = event.target.closest("[data-doc]");
|
||||
if (documentLink) {
|
||||
event.preventDefault();
|
||||
openDocument(documentLink.dataset.doc);
|
||||
}
|
||||
if (event.target.closest("[data-action='menu']")) toggleMenu();
|
||||
const languageButton = event.target.closest("[data-language]");
|
||||
if (languageButton && languageButton.dataset.language !== state.language) {
|
||||
state.language = languageButton.dataset.language;
|
||||
localStorage.setItem("reme-docs-language", state.language);
|
||||
state.query = "";
|
||||
searchInput.value = "";
|
||||
renderChrome();
|
||||
openDocument(state.language === "zh" ? "readme-zh" : "readme-en");
|
||||
}
|
||||
});
|
||||
|
||||
searchInput.addEventListener("input", () => {
|
||||
state.query = searchInput.value;
|
||||
renderNavigation();
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
||||
event.preventDefault();
|
||||
searchInput.focus();
|
||||
}
|
||||
if (event.key === "Escape") closeMenu();
|
||||
});
|
||||
|
||||
backdrop.addEventListener("click", closeMenu);
|
||||
window.addEventListener("popstate", (event) => openDocument(event.state?.doc || new URLSearchParams(location.search).get("doc"), false));
|
||||
|
||||
const manifest = await fetch(`${baseUrl}content/manifest.json`).then((response) => response.json());
|
||||
state.documents = manifest.documents;
|
||||
renderChrome();
|
||||
await openDocument(new URLSearchParams(location.search).get("doc"), false);
|
||||
160
github-pages/src/styles.css
Normal file
160
github-pages/src/styles.css
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
:root {
|
||||
color: #17221d;
|
||||
background: #f4f7f5;
|
||||
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
--ink: #17221d;
|
||||
--muted: #65716a;
|
||||
--line: #dce5e0;
|
||||
--paper: #ffffff;
|
||||
--green: #087f6a;
|
||||
--blue: #3156d9;
|
||||
--green-soft: #e5f5ef;
|
||||
--code: #f3f5f2;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
html { scroll-behavior: smooth; scroll-padding-top: 92px; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
background:
|
||||
radial-gradient(circle at 8% 9%, rgba(27, 193, 164, 0.06), transparent 26rem),
|
||||
#f4f7f5;
|
||||
}
|
||||
button, input { font: inherit; }
|
||||
a { color: inherit; }
|
||||
|
||||
.topbar {
|
||||
position: fixed;
|
||||
inset: 0 0 auto 0;
|
||||
z-index: 30;
|
||||
height: 66px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 28px;
|
||||
border-bottom: 1px solid rgba(213, 225, 219, 0.85);
|
||||
background: rgba(250, 252, 251, 0.88);
|
||||
backdrop-filter: blur(18px) saturate(140%);
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 11px; color: var(--ink); text-decoration: none; font-weight: 760; }
|
||||
.brand-mark {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 11px;
|
||||
color: white;
|
||||
background: linear-gradient(145deg, #19c9b0, #3156d9 82%);
|
||||
box-shadow: 0 7px 18px rgba(24, 123, 114, 0.2);
|
||||
font-family: Georgia, serif;
|
||||
font-size: 21px;
|
||||
}
|
||||
.brand-divider { width: 1px; height: 20px; background: var(--line); margin-left: 2px; }
|
||||
.brand-section { color: var(--muted); font-weight: 520; }
|
||||
.top-actions { display: flex; align-items: center; gap: 18px; }
|
||||
.github-link, .official-docs-link { color: #37443d; text-decoration: none; font-size: 13px; font-weight: 650; }
|
||||
.github-link:hover, .official-docs-link:hover { color: var(--green); }
|
||||
.official-docs-link { padding: 8px 12px; border: 1px solid #d7e5df; border-radius: 9px; background: rgba(255, 255, 255, 0.72); }
|
||||
.language-switch { display: flex; padding: 3px; border: 1px solid var(--line); border-radius: 9px; background: #f5f7f4; }
|
||||
.language-switch button { padding: 5px 9px; border: 0; border-radius: 6px; color: var(--muted); background: transparent; cursor: pointer; font-size: 12px; font-weight: 700; }
|
||||
.language-switch button.active { color: var(--ink); background: white; box-shadow: 0 1px 3px rgba(20, 40, 30, 0.1); }
|
||||
.menu-button { display: none; border: 1px solid var(--line); border-radius: 8px; background: white; padding: 7px 10px; cursor: pointer; }
|
||||
|
||||
.docs-shell { display: grid; grid-template-columns: 276px minmax(0, 1fr) 224px; max-width: 1540px; min-height: 100vh; margin: 0 auto; padding-top: 66px; }
|
||||
.sidebar { position: sticky; top: 66px; height: calc(100vh - 66px); padding: 25px 20px 18px; overflow-y: auto; border-right: 1px solid var(--line); background: rgba(247, 250, 248, 0.78); }
|
||||
.search-box { display: flex; align-items: center; gap: 8px; height: 41px; padding: 0 11px; border: 1px solid #d8e3dd; border-radius: 11px; color: #7a857e; background: rgba(255, 255, 255, 0.84); box-shadow: 0 5px 18px rgba(29, 65, 48, 0.035); }
|
||||
.search-box:focus-within { border-color: #78aa8e; box-shadow: 0 0 0 3px rgba(22, 120, 76, 0.1); }
|
||||
.search-box input { width: 100%; border: 0; outline: 0; color: var(--ink); background: transparent; font-size: 13px; }
|
||||
.search-box kbd { padding: 2px 5px; border: 1px solid var(--line); border-radius: 4px; background: #f7f8f6; font-size: 10px; }
|
||||
.document-nav { padding: 12px 0 52px; }
|
||||
.nav-group { margin-top: 21px; }
|
||||
.nav-group h2 { margin: 0 10px 7px; color: #8a948e; font-size: 10px; font-weight: 800; letter-spacing: 0.11em; text-transform: uppercase; }
|
||||
.nav-group a { position: relative; display: block; padding: 7px 10px 7px 13px; border-radius: 8px; color: #536058; text-decoration: none; font-size: 13px; line-height: 1.4; }
|
||||
.nav-group a:hover { color: var(--ink); background: #f0f3ef; }
|
||||
.nav-group a.active { color: #086b5a; background: linear-gradient(90deg, #dff3ec, #eaf6f2); font-weight: 700; }
|
||||
.nav-group a.active::before { position: absolute; top: 9px; bottom: 9px; left: 0; width: 3px; border-radius: 3px; background: linear-gradient(#17b79d, #3470d8); content: ""; }
|
||||
.empty-state { padding: 24px 10px; color: var(--muted); font-size: 13px; }
|
||||
.sidebar-footer { position: sticky; bottom: -18px; display: flex; align-items: center; gap: 8px; margin: 0 -20px; padding: 14px 22px 18px; border-top: 1px solid var(--line); color: #7c8880; background: #f7faf8; font: 600 10px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.04em; text-transform: uppercase; }
|
||||
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: #29a869; box-shadow: 0 0 0 3px #dff3e8; }
|
||||
|
||||
.article-wrap { min-width: 0; padding: 58px clamp(32px, 5.8vw, 86px) 100px; background: rgba(255, 255, 255, 0.94); }
|
||||
.article { width: 100%; max-width: 820px; margin: 0 auto; }
|
||||
.article-meta { display: flex; gap: 8px; margin-bottom: 22px; color: #7d8d84; font: 600 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.article-meta span:first-child { padding: 3px 8px; border-radius: 999px; color: #08705e; background: #e6f5ef; }
|
||||
.markdown-body { color: #27332d; font-size: 16px; line-height: 1.78; }
|
||||
.markdown-body > :first-child { margin-top: 0; }
|
||||
.markdown-body h1 { margin: 0 0 30px; color: #112019; font-size: clamp(36px, 5vw, 54px); line-height: 1.06; letter-spacing: -0.04em; }
|
||||
.markdown-body h2 { margin: 58px 0 18px; padding-top: 4px; color: #14241c; font-size: 27px; line-height: 1.25; letter-spacing: -0.02em; }
|
||||
.markdown-body h3 { margin: 35px 0 12px; color: #1f3027; font-size: 20px; line-height: 1.35; }
|
||||
.markdown-body p, .markdown-body ul, .markdown-body ol { margin: 14px 0; }
|
||||
.markdown-body li { margin: 5px 0; }
|
||||
.markdown-body a { color: var(--green); text-decoration-color: #9cc8ae; text-underline-offset: 3px; }
|
||||
.markdown-body a:hover { text-decoration-color: var(--green); }
|
||||
.markdown-body img { display: block; max-width: 100%; height: auto; margin: 30px auto; border-radius: 14px; }
|
||||
/* README badges are linked images. Keep them in a compact row instead of applying the figure layout above. */
|
||||
.article[data-group="overview"] .markdown-body > p:has(> a > img[src*="img.shields.io"]) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 7px;
|
||||
max-width: 690px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
.article[data-group="overview"] .markdown-body > p > a > img[src*="img.shields.io"] {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
max-height: 24px;
|
||||
margin: 0;
|
||||
border-radius: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.markdown-body p[align="center"] { text-align: center; }
|
||||
.article[data-group="overview"] .markdown-body > p:first-child img { max-width: min(470px, 72%); margin-top: 8px; filter: drop-shadow(0 18px 25px rgba(44, 85, 164, 0.1)); }
|
||||
.markdown-body code { padding: 2px 5px; border-radius: 5px; background: var(--code); color: #315844; font: 0.88em/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
||||
.markdown-body pre { margin: 24px 0; padding: 19px 21px; overflow-x: auto; border: 1px solid #dce5e0; border-radius: 12px; background: linear-gradient(145deg, #f5f8f6, #f8faf9); box-shadow: inset 3px 0 0 #7bd0b6; }
|
||||
.markdown-body pre code { padding: 0; color: #263b30; background: none; font-size: 13px; }
|
||||
.markdown-body blockquote { margin: 24px 0; padding: 4px 20px; border-left: 3px solid #68aa85; color: #53635a; background: #f5faf7; }
|
||||
.markdown-body table { display: block; width: 100%; margin: 24px 0; overflow-x: auto; border-collapse: collapse; font-size: 14px; }
|
||||
.markdown-body th, .markdown-body td { padding: 10px 13px; border: 1px solid var(--line); text-align: left; }
|
||||
.markdown-body th { background: #f4f6f3; }
|
||||
.markdown-body hr { margin: 44px 0; border: 0; border-top: 1px solid var(--line); }
|
||||
.article-footer { margin-top: 70px; padding-top: 20px; border-top: 1px solid var(--line); }
|
||||
.article-footer a { color: var(--muted); text-decoration: none; font-size: 13px; }
|
||||
.article-footer a:hover { color: var(--green); }
|
||||
.loading-line { width: 55%; height: 12px; margin-top: 40px; border-radius: 9px; background: linear-gradient(90deg, #edf0ec, #f8faf7, #edf0ec); background-size: 200% 100%; animation: loading 1.2s infinite; }
|
||||
@keyframes loading { to { background-position: -200% 0; } }
|
||||
|
||||
.toc-panel { position: sticky; top: 66px; height: calc(100vh - 66px); padding: 58px 24px; overflow-y: auto; border-left: 1px solid #e9efeb; background: rgba(252, 253, 252, 0.92); }
|
||||
.toc h2 { margin: 0 0 12px; color: #8a948e; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; }
|
||||
.toc a { display: block; padding: 5px 0; color: #7a857e; text-decoration: none; font-size: 12px; line-height: 1.45; }
|
||||
.toc a:hover { color: var(--green); }
|
||||
.toc .toc-h3 { padding-left: 12px; }
|
||||
.sidebar-backdrop { display: none; }
|
||||
|
||||
@media (max-width: 1120px) {
|
||||
.docs-shell { grid-template-columns: 250px minmax(0, 1fr); }
|
||||
.toc-panel { display: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.topbar { height: 60px; padding: 0 16px; }
|
||||
.brand-section, .brand-divider, .github-link { display: none; }
|
||||
.official-docs-link { font-size: 12px; }
|
||||
.menu-button { display: block; max-width: 112px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.top-actions { gap: 9px; }
|
||||
.docs-shell { display: block; padding-top: 60px; }
|
||||
.sidebar { position: fixed; z-index: 25; top: 60px; bottom: 0; left: 0; width: min(310px, 86vw); height: auto; transform: translateX(-105%); transition: transform 180ms ease; box-shadow: 16px 0 35px rgba(20, 40, 30, 0.12); }
|
||||
.sidebar.open { transform: translateX(0); }
|
||||
.sidebar-backdrop { position: fixed; z-index: 20; inset: 60px 0 0; width: 100%; border: 0; background: rgba(18, 30, 23, 0.35); }
|
||||
.sidebar-backdrop.visible { display: block; }
|
||||
.article-wrap { padding: 38px 20px 72px; }
|
||||
.article-meta { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.markdown-body { font-size: 15px; }
|
||||
.markdown-body h1 { font-size: 34px; }
|
||||
.markdown-body h2 { margin-top: 46px; font-size: 24px; }
|
||||
.article[data-group="overview"] .markdown-body > p:first-child img { max-width: 84%; }
|
||||
}
|
||||
10
github-pages/vite.config.js
Normal file
10
github-pages/vite.config.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
base: "./",
|
||||
publicDir: ".generated",
|
||||
build: {
|
||||
outDir: "dist",
|
||||
emptyOutDir: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -68,7 +68,7 @@ full = [
|
|||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/agentscope-ai/ReMe"
|
||||
Documentation = "https://docs.agentscope.io/reme"
|
||||
Documentation = "https://reme.agentscope.io"
|
||||
Repository = "https://github.com/agentscope-ai/ReMe"
|
||||
|
||||
[project.scripts]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue